【问题标题】:Something is wrong with my do-while loop involving character position我的 do-while 循环涉及字符位置有问题
【发布时间】:2013-03-04 22:28:06
【问题描述】:

当我运行程序时,输出只是连续的并且不会结束。这里的目标是尝试让 + 一直到左边或右边,然后打印哪一方获胜以及它花了多少圈。

代码现在正在执行,但它只从中间向左和向右移动一个空格,这让我觉得它现在使用 for 循环

package test;

import java.util.Scanner;
import java.lang.Math;

public class Test {

    public static int MAX_LENGTH = 21;
    public static int MIN_LENGTH = 5;

    public static void main(String[] args) {
        Scanner keyboard = new Scanner(System.in);
        System.out.print("Enter the length of the rope: ");
        int ropeLength = keyboard.nextInt();
        while (ropeLength < MIN_LENGTH || ropeLength > MAX_LENGTH || ropeLength % 2 != 1) {
            System.out.println("Thats not a valid length (odd number between 5 and 21)");
            System.out.print("Enter the length of the rope: ");
            ropeLength = keyboard.nextInt();
        }
        char a;
        String flag = " ";
        for (int i = 0; i < ropeLength / 2; i += 1) {
            flag += "-";
        }
        flag += "+";

        for (int i = 0; i < ropeLength / 2; i += 1) {
            flag += "-";
        }
        System.out.println("");


        do {
            flag = "";
            double rand = Math.random();
            int i;
            if (rand > 0.5) {

                for (i = 0; i < (ropeLength / 2) - 1; i++) {
                    flag += "-";
                    }

                flag += "+";

                for (i = 0; i < (ropeLength / 2) + 1; i++) {
                    flag += "-";
                }
                System.out.println( flag );
            }
            if (rand < 0.5) {

                for (i = 0; i < (ropeLength / 2) + 1; i++) {
                    flag += "-";
                    }

                flag += "+";

                for (i = 0; i < (ropeLength / 2) - 1; i++) {
                    flag += "-";
                   }
                   System.out.println( flag );
                } 

        } while (flag.charAt(1) != '+' || flag.charAt(ropeLength) != '+');

        if (flag.charAt(0) == '+') {
            System.out.println("\nLeft side wins!");
        }
        else {
            System.out.println("\nRight side wins!");
        }    
        System.out.println("It took steps");
    }
}

【问题讨论】:

  • 连续输出是什么样的?
  • ----+---------+--------+----等

标签: java loops while-loop do-while


【解决方案1】:

你需要注意旗帜的位置。目前,您只将标志放在中心左侧或右侧的一个位置。您可能希望将您的标志打印方法拉入一个辅助方法中,以简化可读性并让您更清楚地了解您需要跟踪的内容。

一旦你用调用这个方法替换了你的三个打印方法,你应该更清楚你需要跟踪什么并作为参数传递以使一切正常工作。

这样的事情应该让你开始:

public static void printFlag(int ropeLength, int flagPosition) {
    for (int i = 0; i < flagPosition; i += 1) {
        System.out.print("-");
    }
    System.out.print("+");

    for (int i = flagPosition + 1; i < ropeLength; i += 1) {
        System.out.print("-");
    }
    System.out.println();
}

注意:使用StringBuilder 而不是一堆print() 调用可能是个好主意,但我将把它作为练习留给读者。

【讨论】:

    【解决方案2】:

    您的代码中的逻辑存在多个问题。

    1) 在你的 do-while 循环中,你总是只是不断地附加到标志。这意味着对于每次迭代,您的标志只会变得更大,它实际上并没有移动您在其中的+。您可以有一个名为“nextState”的临时变量来生成下一个状态,然后在最后设置等于它的标志。

    代码:

    String nextState = "";
    if (rand > 0.5) {
        for (i = 0; i < (ropeLength / 2) - 1; i++) {
            nextState += "-";
        }
        nextState += "+";
        for (i = 0; i < (ropeLength / 2) + 1; i++) {
            nextState += "-";
        }
        flag = nextState;
        System.out.println(flag);
    }  
    

    2) 您正在检查flag.charAt(1)=='+'flag.charAt(ropeLength)=='+'。由于数组有一个基于 0 的索引,这是不正确的,您实际上分别需要 0ropeLength-1。 (我确实注意到你在 do-while 循环下正确地做到了)。

    3) 你的 do-while 循环的问题是,如果你更正错误 1 ​​和 2,你肯定会将 + 左右移动,但是你永远无法将它移动到位置 @987654328 @(一直向左)或定位ropeLength-1(一直向右)与您当前的逻辑。可以做这样的事情,你也可以为另一个 if 做类似的事情。

    if (rand > 0.5) {
      i = 0;
      while (i + 1 < flag.length() && flag.charAt(i + 1) != '+') {
        nextState += "-";
        i++;
      }
      nextState += "+";
      i++;
      while (i < flag.length()) {
        nextState += "-";
        i++;
      }
      flag = nextState;
    }
    

    4) 你初始化了flag = " ";,但你只想要flag = "";(一个空字符串)作为标志只包含-和一个+

    5) while (flag.charAt(0) != '+' || flag.charAt(ropeLength - 1) != '+'); 不正确。它应该是&amp;&amp;,因为你原来的陈述总是正确的,循环永远不会结束。只有在开头和结尾都有+ 时,您的原始陈述才会是错误的,这是不可能的。

    6) 不是真正的问题,但对于您的 if (rand &gt; 0.5),您可以使用 if-else 而不是两个 if。如果 rand 正好等于 0.5,你的代码什么也不做。由于您必须计算步数,因此您需要将其中一个更改为 rand &lt;= 0.5rand &gt;= 0.5 或仅使用 if-else。

    一旦你解决了这些问题。你已准备好出发。辛苦了!

    【讨论】:

    • 我需要将 Camerons 的东西合并到这个答案中。我这样做的长度 = 5。我没有注意到您也错误地移动了+。我正在修复它。
    • 线程“主”java.lang.StringIndexOutOfBoundsException 中的异常:字符串索引超出范围:-1
    • 你永远不应该得到 -1 索引越界错误,因为你永远不会减少 i。但这是我能想出的最接近的代码,而不会改变你处理这个问题的方式。我将更多地编辑这个问题。剧透:pastebin.com/NnFBJGsP
    • 由于对于足够大的输入,此循环可能永远不会结束,因此使用int 作为 step 可能是个坏主意。我应该使用 long 甚至更好的 BigInteger 来代替。此外,StringBuilder 和 StringBuffer 是理想的数据类型,而不是用于 nextState 的 String,因为您执行大量字符串追加,这种方式的内存效率非常低。
    【解决方案3】:

    你永远不会在每次迭代开始时重置你的标志

    正如 knoight 所说,你需要 && 运算符

    你需要这样的东西:

    do {
    flag = "";
    ... your existing code
    
     } while ( (flag.charAt(1) != '+') && (flag.charAt(ropeLength) != '+') );
    

    看起来你的旗帜会随着我上面提出的修复随机跳动。也许您只想在每次迭代中将标志向左或向右移动一个位置?

    你可以这样做:

    int flagpos = (ropeLength / 2)+1;
    do {
        flag = "";
        double rand = Math.random();
        int i;
        if (rand > 0.5) {
            flagpos++;
        else
            flagpos--;
        for (i = 0; i < flagpos - 1; i++) 
            flag += "-";
        flag += "+";
        for (i = flagpos + 1; i < ropeLength ; i++) 
            flag += "-";
    
            System.out.println( flag );
        } while (flag.charAt(1) != '+' || flag.charAt(ropeLength) != '+');
    

    【讨论】:

    • 好的,但现在 + 只是连续地左右移动 1 个空格。谢谢
    • ---+----- -----+--- -----+--- ---+----- ---+-- --- ---+----- -----+--- ---+----- -----+--- ---+----- -- -+----- ---+-----
    • hm 并没有像我想象的那样。所有这些都在彼此之上,尽管这很好。现在唯一的问题是它不再向左或向右移动,只是停留在那些 2
    • 我认为循环实际上根本没有将它们向右或向左移动。您反复将“+”设置在中点的左侧或右侧,但每次都是相同的位置。您需要跟踪“+”的最后一个位置,然后根据该位置向左/向右移动。
    • 既然您已经跟踪了 flagpos,您还应该执行 while( flagpos != 1 && flagpos !=ropeLength ) 并将构造的标志仅用于输出。虽然不是真的错误,但我相信第一个 for 在语义上会更好,因为 for( i = 1; i
    【解决方案4】:

    您需要更改最后一行,来自:

    while (flag.charAt(1) != '+' || flag.charAt(ropeLength) != '+');

    while (flag.charAt(0) != '+' &amp;&amp; flag.charAt(ropeLength) != '+');

    使用|| 意味着这些条件中只有一个必须为真,并且由于您使用的是while 循环,因此您是说如果第一个位置不等于+ 或者最后一个位置不等于等于+,那么您希望循环继续。


    【讨论】:

    • 线程“主”java.lang.StringIndexOutOfBoundsException 中的异常:字符串索引超出范围:9 at java.lang.String.charAt(String.java:695) at test.Test.main(Test .java:67) Java 结果:1
    【解决方案5】:

    如前所述,以下将起作用。

        do {
           flag = "";
           //do stuff
        } while (flag.charAt(1) != '+' && flag.charAt(ropeLength-1) != '+');
    

    问题是你掷硬币来移动绳子,绳子越长,你到达终点的机会就越小。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-26
      • 2021-01-31
      相关资源
      最近更新 更多