For 循环可以在当前迭代中 'see' 即将到来的值吗?

For loop can 'see' forthcoming values in current iteration?

我正在完成 CodingBat 的 Java 练习,我遇到了 CountXX problem,它计算 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 循环的一次迭代如何能够 'look ahead' 到下一次迭代?在这种情况下,它能够看到一个字符 下一个迭代字符的值。如果它可以展望未来的迭代,那么 'defeat the point' 不是整数递增吗? (我肯定漏掉了什么!)

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

你让他看前面一个字

只是因为您在当前索引处使用 charAt + 1 :

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

If it can look ahead to future iterations, doesn't that 'defeat the point' of incrementing by integer?

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

它不会击败整数递增点。如果您想使用其他算法来执行此操作,则必须创建一个临时变量来保存最后一个字符或一个计数器。恕我直言,这样更简单。

迭代不是 "looking ahead" 或类似的东西。事实上,for 循环并不知道您正在遍历字符串的索引。它只知道你想要它

  • 在开始迭代前设置i = 0
  • i大于某个数时结束迭代,
  • 每次迭代后 i 增加 1

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

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

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

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

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

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

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

for 循环总是可以重构为带有中断条件和计数器语句的无限循环*:

//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") 甚至不止一个。但这超出了日常使用范围。