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