我正在通过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循环的迭代如何能够“向前看”到下一次迭代?在这种情况下,它能够看到一个字符的值和以下迭代的字符。如果它可以展望未来的迭代,那么这不是“打败整数递增的点”吗? (我当然错过了一些东西!)
答案 0 :(得分:2)
迭代不是“向前看”或类似的东西。实际上,for
循环并不知道您正在迭代字符串的索引。它只知道你想要它
i = 0
i
变得大于某个数字时结束迭代,i
增加1
。就是这样。 i
变量作为字符串索引的任何解释都是在循环体内完成的。
进入循环后,您可以指望i
处于特定范围内(即从零,包括,到str.length() - 1
,独占)。这使得i
成为从字符串中获取两个相邻字符的合适候选者,这正是您的代码所做的。
答案 1 :(得分:1)
if ((str.charAt(i) == 'x') && (str.charAt(i+1) == 'x'))
^
你告诉他要看一个角色。
答案 2 :(得分:1)
仅仅因为你在当前索引+ 1使用charAt
:
if ((str.charAt(i) == 'x') && (str.charAt(i+1) == 'x'))
如果它可以展望未来的迭代,那不是'打败了 点'按整数递增?
由于您正在寻找序列xx
出现在字符串中的时间,因此您需要检查当前和下一个字符,这就是算法展望的原因。
它没有击败按整数递增的点。如果您希望使用其他算法,则必须创建一个临时变量来保存最后一个字符或计数器。恕我直言,这样简单明了。
答案 3 :(得分:0)
如果你是新人,唯一愚蠢的问题是你没有问过的问题:)
关键是这一行:((str.charAt(i) == 'x') && (str.charAt(i+1) == 'x'))
基本上,在每次迭代时,它都会检查元素i和元素i + 1。
这并没有打败一次迭代1的点;它会检查0和1,然后是1和2,然后是2和3,依此类推;如果我们每次增加2,那么我们就会错过连续两个x的情况,但第一个是在奇数位置(即&#34; abcxxdef&#34) ;)
如上所述,你需要提前停止一个位置(在str.length() - 1),因为表达式的后半部分将1添加到idex,这将使其超出界限引起异常。
答案 4 :(得分:0)
注意: 我知道这不是问题的完整答案;将其视为对其他答案的补充。
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")
,甚至不只是一个。但这超出了每天的使用范围。