【问题标题】:For loop can 'see' forthcoming values in current iteration?For 循环可以“看到”当前迭代中即将出现的值吗?
【发布时间】:2015-06-01 00:35:34
【问题描述】:

我正在完成 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 循环的迭代如何能够“向前看”到下一次迭代?在这种情况下,它能够看到一个字符下一个迭代字符的值。如果它可以展望未来的迭代,那不是“打败点”以整数递增吗? (我当然错过了什么!)

【问题讨论】:

  • For 循环用于执行循环直到满足条件,它不会“查看”任何地方。您只需使用它来控制 i 可以更改的范围,然后计算 another 范围,您必须在字符串内检查(另一个范围由两个元素组成:ii+1 )。
  • 这样想:您正在使用某个索引进行迭代。而已。您的循环只是一个索引i,它会增加直到达到某个限制。你在循环中做什么完全是你的决定。您可以使用该索引i 来做任何事情。您可以随意使用i!您可以将2 * i 用于i * i,或者在您的情况下使用i + 1 来获取下一个字符。你的方法非常好。循环本身不会“看到”任何东西。它只是为您提供了一个构造,让您拥有一个不断增加的索引i 来使用您想要的方式。这就是你想要思考这些事情的方式

标签: java loops for-loop iteration charat


【解决方案1】:

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

  • 在开始迭代之前设置i = 0
  • i大于一定数量时结束迭代,并且
  • 每次迭代后将i 增加1

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

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

【讨论】:

    【解决方案2】:
     if ((str.charAt(i) == 'x') && (str.charAt(i+1) == 'x'))
                                                ^
    

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

    【讨论】:

    • 我明白……但我的意思是它能够在当前迭代中看到字符串中的下一个字符(我觉得很难解释。)
    • @alanbuchanan:如果您愿意,您可以在每个迭代步骤中看到 所有 个字符。 String 是一个随机访问结构。即使没有循环,您也可以调用charAt(arbitraryIndex)
    • @alanbuchanan 我不知道你到底是什么意思,但如果这是问题的话,i+1 不会增加你当前的循环..
    【解决方案3】:

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

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

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

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

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

    【讨论】:

      【解决方案4】:

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

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

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

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

      【讨论】:

      • 我理解你引用的那一行和 for 循环的概念。我认为我没有很好地解释我的问题。
      【解决方案5】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-01-03
        • 1970-01-01
        • 1970-01-01
        • 2019-06-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-04
        相关资源
        最近更新 更多