我正在尝试空运行本书中的英语标尺方法,但是空运行有点令人困惑,并且我的输出和原始输出是不同的。

public static void drawRuler(int nInches, int majorlength)
{
  drawLine(majorLength, 0);
  for (int j =1; j<= nInches, j++)
  {
   drawInterval(majorLength-1);
   drawLine(majorLength, j);
 }
}

private static void drawInterval (int centralLength)
{
 if (centralLength>=1)
 {
  drawInterval(centralLength - 1);
  drawLine(centralLength);
  drawInterval(centrakLength-1);
 }
}

public static void drawLine(int tickLength, int tickLabel)
{
 for (int j=0; j<ticklength; j++)
   System.out.print("-")
 if (tickLabel>=0)
  System.out.print(" "+tickLable);
 System.out.print("\n");
}

private static void drawLine(int tickLength)
{
  drawLine(tickLength, -1);
}


首先,我输入nInches = 1 and majorlength 3

1- drawLine将被(3,0)//刻度长度和ticklabel调用

public static void drawLine(3, 0)
    {
     for (int j=0; j<3; j++)
       System.out.print("-")
     if (tickLabel>=0)
      System.out.print(" "+tickLable);
     System.out.print("\n");
    }


输出:

--- 0


2-现在下面的循环将从drawRuler函数运行

for (int j =1; j<=1, j++)
      {
       drawInterval(majorLength-1);


* Point1:均线以上将调用drawInterval(2)?*

drawLine(majorLength, j);
     }


3-我们以2作为参数移至drawInterval函数

private static void drawInterval (2)
    {
     if (centralLength>=1)   // true
     {
      drawInterval(centralLength - 1);
 **Point 2: what the point of calling same function with 1 ? and will it call itself again without drawing anything? and function will go on nextline after drawInterval become 0?**


drawLine(centralLength);
      drawInterval(centrakLength-1);
     }
    }


第三点:drawLine(tickLength, -1);为什么使用此-1

最佳答案

看来您已从Data Structures and Algorithms in Java书中获取了代码。

但是您的代码甚至无法编译,语法错误和变量误称太多。您是否通过扫描+ OCR从书中获得了该源代码,而没有尝试使用Java运行它?

因此,首先让我们修复错误,然后将此片段代码转换为具有main方法的类,对吗?

package de.scrum_master.stackoverflow;

public class EnglishRuler {
  public static void main(String[] args) {
    drawRuler(2, 4);
  }

  public static void drawRuler(int nInches, int majorLength) {
    drawLine(majorLength, 0);
    for (int j = 1; j <= nInches; j++) {
      drawInterval(majorLength - 1);
      drawLine(majorLength, j);
    }
  }

  private static void drawInterval(int centralLength) {
    if (centralLength >= 1) {
      drawInterval(centralLength - 1);
      drawLine(centralLength);
      drawInterval(centralLength - 1);
    }
  }

  private static void drawLine(int tickLength, int tickLabel) {
    for (int j = 0; j < tickLength; j++)
      System.out.print("-");
    if (tickLabel >= 0)
      System.out.print(" " + tickLabel);
    System.out.print("\n");
  }

  private static void drawLine(int tickLength) {
    drawLine(tickLength, -1);
  }
}


drawRuler(1, 3)打印:

--- 0
-
--
-
--- 1


drawRuler(1, 5)打印:

----- 0
-
--
-
---
-
--
-
----
-
--
-
---
-
--
-
----- 1


drawRuler(2, 4)打印:

---- 0
-
--
-
---
-
--
-
---- 1
-
--
-
---
-
--
-
---- 2


这完全符合预期。现在让我们向程序添加一些可选的调试输出:

package de.scrum_master.stackoverflow;

public class EnglishRuler {
  private static boolean DEBUG = true;
  private static String indent = "";

  public static void main(String[] args) {
    drawRuler(1, 3);
  }

  public static void drawRuler(int nInches, int majorLength) {
    if (DEBUG)
      System.out.println("drawRuler(" + nInches + ", " + majorLength + ")");
    drawLine(majorLength, 0);
    for (int j = 1; j <= nInches; j++) {
      drawInterval(majorLength - 1);
      drawLine(majorLength, j);
    }
  }

  private static void drawInterval(int centralLength) {
    indent += "  ";
    if (DEBUG)
      System.out.println(indent + "drawInterval(" + centralLength + ")");
    if (centralLength >= 1) {
      drawInterval(centralLength - 1);
      drawLine(centralLength);
      drawInterval(centralLength - 1);
    }
    indent = indent.substring(2);
  }

  private static void drawLine(int tickLength, int tickLabel) {
    indent += "  ";
    if (DEBUG)
      System.out.println(indent + "drawLine(" + tickLength + ", " + tickLabel + ")");
    for (int j = 0; j < tickLength; j++)
      System.out.print("-");
    if (tickLabel >= 0)
      System.out.print(" " + tickLabel);
    System.out.print("\n");
    indent = indent.substring(2);
  }

  private static void drawLine(int tickLength) {
    drawLine(tickLength, -1);
  }
}


只要DEBUGfalse,这不会更改输出。如果将其设置为true,则drawRuler(1, 3)的日志将变为:

drawRuler(1, 3)
  drawLine(3, 0)
--- 0
  drawInterval(2)
    drawInterval(1)
      drawInterval(0)
      drawLine(1, -1)
-
      drawInterval(0)
    drawLine(2, -1)
--
    drawInterval(1)
      drawInterval(0)
      drawLine(1, -1)
-
      drawInterval(0)
  drawLine(3, 1)
--- 1


在那里,您有一个自动生成的空运行版本。

因此,对于您的问题:


  首先,我要输入nInches = 1majorlength = 3
  
  1)drawLine将被(3,0)调用(tickLengthtickLabel


正确。


  Point1:意思是在行上方会调用drawInterval(2)


正确。


  第三点:drawLine(tickLength, -1)。为什么我们使用此-1


因为在drawLine(int tickLength, int tickLabel)中它说:

    if (tickLabel >= 0)
      System.out.print(" " + tickLabel);


因此,使tickLabel的值小于零只是避免在主间隔而非子间隔较小时打印标签的一种方法。



更新:我还根据递归级别将缩进添加到了带有调试输出的程序版本中,并且还更新了日志输出以使其缩进,以更好地理解OP。



更新2:您可以通过内联便捷方法drawLine(int tickLength)来简化程序,如下所示:

  private static void drawInterval(int centralLength) {
    // ...
      drawInterval(centralLength - 1);
      drawLine(centralLength, -1);  // Note the additional ", -1"
      drawInterval(centralLength - 1);
    // ...
  }


然后将其删除,因为现在不再使用它:

  // Delete me!
  private static void drawLine(int tickLength) {
    drawLine(tickLength, -1);
  }




更新3:因为您似乎很恼火,以至于我没有为便捷方法drawLine(int tickLength)打印日志输出,所以这也是原始程序的又一个扩展版本,也为该方法生成了输出,现在可以精确地复制笔和纸了跑:

package de.scrum_master.stackoverflow;

public class EnglishRuler {
  private static boolean DEBUG = true;
  private static String indentText = "";

  public static void main(String[] args) {
    drawRuler(1, 3);
  }

  public static void drawRuler(int nInches, int majorLength) {
    debugPrint("drawRuler(" + nInches + ", " + majorLength + ")");
    drawLine(majorLength, 0);
    for (int j = 1; j <= nInches; j++) {
      drawInterval(majorLength - 1);
      drawLine(majorLength, j);
    }
  }

  private static void drawInterval(int centralLength) {
    indent();
    debugPrint("drawInterval(" + centralLength + ")");
    if (centralLength >= 1) {
      drawInterval(centralLength - 1);
      drawLine(centralLength);
      drawInterval(centralLength - 1);
    }
    dedent();
  }

  private static void drawLine(int tickLength, int tickLabel) {
    indent();
    debugPrint("drawLine(" + tickLength + ", " + tickLabel + ")");
    for (int j = 0; j < tickLength; j++)
      System.out.print("-");
    if (tickLabel >= 0)
      System.out.print(" " + tickLabel);
    System.out.print("\n");
    dedent();
  }

  private static void drawLine(int tickLength) {
    indent();
    debugPrint("drawLine(" + tickLength + ")");
    drawLine(tickLength, -1);
    dedent();
  }

  private static void debugPrint(String message) {
    if (DEBUG)
      System.out.println(indentText + message);
  }

  private static void indent() {
    indentText += "  ";
  }

  private static void dedent() {
    indentText = indentText.substring(2);
  }
}


更新后的控制台日志变为:

drawRuler(1, 3)
  drawLine(3, 0)
--- 0
  drawInterval(2)
    drawInterval(1)
      drawInterval(0)
      drawLine(1)
        drawLine(1, -1)
-
      drawInterval(0)
    drawLine(2)
      drawLine(2, -1)
--
    drawInterval(1)
      drawInterval(0)
      drawLine(1)
        drawLine(1, -1)
-
      drawInterval(0)
  drawLine(3, 1)
--- 1


我发现这是不必要的,但如果有帮助,我会感到很高兴。

07-24 20:20