为了账号安全,请及时绑定邮箱和手机立即绑定

英文标尺递归问题

英文标尺递归问题

PIPIONE 2023-09-06 15:41:00
我正在尝试试运行书中的英语标尺方法,但是试运行有点令人困惑,而且我的输出和原始输出不同。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- 将使用 (3,0) // 刻度长度和刻度标签调用drawLinepublic 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");    }输出:--- 02-现在下面的循环将从drawRuler函数运行for (int j =1; j<=1, j++)      {       drawInterval(majorLength-1);* Point1: 意味着上面的线会调用drawInterval(2) ?*drawLine(majorLength, j);     }3-我们转到以 2 作为参数的函数drawIntervalprivate 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);     }    }Point3:drawLine(tickLength, -1);为什么我们用这个-1?
查看完整描述

1 回答

?
幕布斯7119047

TA贡献1794条经验 获得超8个赞


你的代码甚至无法编译,有很多语法错误和变量用词不当。您是否通过扫描 + 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);

  }

}

DEBUG只要是,这就不会改变输出false。如果将其设置为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 = 1并且majorlength = 3,


1)drawLine将用(3,0)(tickLength和tickLabel)调用


正确的。


Point1:上面那行的意思是会调用drawInterval(2)?


正确的。


第3点: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

我发现这是不必要的,但如果它对你有帮助,我很高兴。


查看完整回答
反对 回复 2023-09-06
  • 1 回答
  • 0 关注
  • 91 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信