【问题标题】:Why does the if-block not run for the final case?为什么 if-block 不为​​最终案例运行?
【发布时间】:2016-12-05 09:14:11
【问题描述】:

考虑下面的代码,它计算数组中每个元素的数量:

public static void getCounts(int[] list) {
    int current = list[0];
    int count = 0;
    for (int i = 0; i < list.length; i++, count++) {
        if (list[i] > current) {
            System.out.println(current + " occurs " + count + timeOrTimes(count));
            current = list[i];
            count = 0;
        }
    }
   System.out.println(current + " occurs " + count + timeOrTimes(count));
}

对于这个问题,请假设list 是按升序排列的。如果list[1, 1, 2, 3, 4, 4],例如,输出是:

1 occurs 2 times
2 occurs 1 time
3 occurs 1 time
4 occurs 2 times

现在,如果我去掉 for 循环之后的 println,即

public static void getCounts(int[] list) {
    int current = list[0];
    int count = 0;
    for (int i = 0; i < list.length; i++, count++) {
        if (list[i] > current) {
            System.out.println(current + " occurs " + count + timeOrTimes(count));
            current = list[i];
            count = 0;
        }
    }
   // System.out.println(current + " occurs " + count + timeOrTimes(count));
}

然后使用相同的示例输入,输出变为:

1 occurs 2 times
2 occurs 1 time
3 occurs 1 time

换句话说,如果list[i] 是数组的最大值,则if不会执行。为什么会这样?对于上面的例子,第一个4的索引是i = 4list[4] &gt; 3,所以条件语句满足了,但还是不会执行。

如何调整代码以使if 块适用于所有情况?

谢谢

【问题讨论】:

  • 这个问题属于初学者水平,但经过深思熟虑,写得很好,达到了所有必要的要点。我希望更多的初学者问题和这个一样好。

标签: java arrays if-statement for-loop


【解决方案1】:

最后的println 是必要的,因为您在list[i] 的值发生更改 时触发打印语句,并打印previous 值的结果。在程序结束时没有检测到最后一个“变化”,因此您需要单独处理最后一个案例。

这(循环后需要最终操作)是一种标准编码模式,只要序列中的变量更改触发批处理结束时的操作,就会发生这种模式。一种思考方式是,有一个虚拟值,在数组末尾之后,它总是大于任何可能的先前值,并表示数据结束。无需对其进行测试或实际实现它,但您仍然需要对操作进行编码(在您的情况下为println)。

该操作可能要复杂得多,在这种情况下,您需要将其封装在一个方法中以避免代码重复。将println 封装在方法outputCount(int value, int count) 中,您的代码可能略微受益。 例如

private void outputCount(int value, int count) {
    System.out.println(value + " occurs " + count + timeOrTimes(count));
}

对于您的用例来说,这几乎是不值得的,但如果批处理结束操作远远超过 1 行代码,我肯定会为它编写一个方法,而不是重复代码。

【讨论】:

  • 啊,这更有意义。感谢您的简洁解释。只是为了确保我理解正确,对于依赖于变量更改的 for 循环,应该有一些代码在循环完成后执行以显示最终更改,对吧?
  • 这是正确的,当您故意跑出数组的末尾时,您必须处理最后一批没有更改“之后”的数据以触发求和(或其他) .请参阅我的扩展答案。
  • 您介意展示如何封装此代码吗?我是 Java 初学者,还没有学过这个概念。
  • 已更新。您已经使用timeOrTimes() 完成了一次 :-)
  • 封装可以有多种含义,但它只是意味着对某些东西进行包装。更正式地说,它指的是一个类对外部世界隐藏其内部结构并仅公开其 API 或与客户端交互的“合同”。
猜你喜欢
  • 2019-10-13
  • 2018-01-08
  • 2020-07-28
  • 1970-01-01
  • 2010-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多