3

我正在完成 CodingBat 的 Java 练习,遇到了CountXX 问题,它计算xx在字符串中出现的次数。这是我解决它的方法(我没想到它会起作用):

int countXX(String str) {
    int count = 0;

    for (int i = 0; i < str.length() - 1; i++) {

        if ((str.charAt(i) == 'x') && (str.charAt(i+1) == 'x'))
            count++;
    }

    return count;
}

我的问题是:for 循环的迭代如何能够“向前看”到下一次迭代?在这种情况下,它能够看到一个字符的值下一个迭代的字符。如果它可以展望未来的迭代,那不是“打败点”以整数递增吗?(我当然错过了一些东西!)

4

5 回答 5

2

迭代不是“向前看”或类似的东西。事实上,for循环并不知道您正在迭代字符串的索引。它只知道你想要它

  • i = 0在开始迭代之前设置
  • i当大于某个数时结束迭代,并且
  • 每次迭代后递增i1

就是这样。将变量作为字符串索引的任何解释i都是在循环体内完成的。

一旦进入循环,您就可以指望在i某个范围内(即,从零(包括)到str.length() - 1,不包括在内)。这使得i从字符串中获取两个相邻字符的合适候选者,这正是您的代码所做的。

于 2015-03-27T15:58:14.350 回答
1
 if ((str.charAt(i) == 'x') && (str.charAt(i+1) == 'x'))
                                            ^

你告诉他看到前面的一个角色。

于 2015-03-27T15:53:24.410 回答
1

仅仅因为您使用charAtat 当前索引 + 1 :

if ((str.charAt(i) == 'x') && (str.charAt(i+1) == 'x'))

如果它可以展望未来的迭代,那不是“打败点”以整数递增吗?

由于您正在寻找序列xx在字符串中出现的次数,因此您需要检查当前字符和下一个字符,这就是算法向前看的原因。

它不会破坏按 integer 递增的点。如果你想用其他算法来做,你必须创建一个临时变量来保存最后一个字符,或者一个计数器。恕我直言,这种方式更简单。

于 2015-03-27T15:53:28.760 回答
0

如果您是新手,唯一愚蠢的问题就是您没有问的问题:)

关键是这一行:((str.charAt(i) == 'x') && (str.charAt(i+1) == 'x')) 基本上,在每次迭代中,它都会检查元素 i 和元素 i+1。

这并没有破坏一次迭代 1 的意义;它将检查 0 和 1,然后检查 1 和 2,然后检查 2 和 3,以此类推;如果我们每次都增加 2,那么我们就会错过连续有两个 x,但第一个 x 位于奇数位置(即“abcxxdef”)的情况。

如上所述,您需要提前停止一个位置(在 str.length()-1 处),因为表达式的后半部分将 1 添加到 idex,这会将其推出边界并导致异常。

于 2015-03-27T15:59:55.160 回答
0

注意:我了解这不是问题的完整答案;将其视为其他答案的补充。

一个 for 循环总是可以重构为一个无限循环,带有一个 break 条件和一个 counter 语句*:

//for(/*initializer*/; /*break condition*/; /*end statement*/) { /*body statement block*/ }
for(int i = 0; i < length; i++) {
    /* do something */
}

等于:

{
    int i = 0;
    while(true) {
        if(i < length) {
            break;
        }
        /* do something */
        i++;
    }
}

*不一定,取而代之的i++是任何陈述,例如System.out.println("foo")甚至不止一个。但这超出了日常使用范围。

于 2015-03-27T16:09:33.663 回答