【问题标题】:Loop structure for histogram直方图的循环结构
【发布时间】:2017-02-26 20:47:19
【问题描述】:

我正在尝试编写一个 Java 程序,该程序会为数组中每次出现的值生成一个星号直方图。

如果元素分别为 0、1、2、3、4、5、6、7、8、9,则输出应在每次出现时都有一个星号。例如,

0:*
1:*
2:*
3:*
4:*
5:*
6:*
7:*
8:*
9:*

但是,我的输出是

0:**********
1:
2:
3:
4:
5:
6:
7:
8:
9:

下面的代码是我自己的。

public static void drawHistogram(double[] array) {

    String count = "";

    for (int i = 0; i < array.length; i++) {
        if (array[i] >= 0 && array[i] < 1) {
            count += "*";
        } else if (array[i] >= 1 && array[i] < 2) {
            count += "*";
        } else if (array[i] >= 2 && array[i] < 3) {
            count += "*";
        } else if (array[i] >= 3 && array[i] < 4) {
            count += "*";
        } else if (array[i] >= 4 && array[i] < 5) {
            count += "*";
        } else if (array[i] >= 5 && array[i] < 6) {
            count += "*";
        } else if (array[i] >= 6 && array[i] < 7) {
            count += "*";
        } else if (array[i] >= 2 && array[i] < 8) {
            count += "*";
        } else if (array[i] >= 2 && array[i] < 9) {
            count += "*";
        } else if (array[i] >= 9 && array[i] < 10) {
            count += "*";
        } else if (array[i] >= 10 && array[i] < 11) {
            count += "*";
        }
    }
    for (int j = 0; j <= 10; j++) {
        System.out.print(j + count);
        count = "";
        System.out.println();
    }
}

我该如何解决这个问题?

【问题讨论】:

  • 看起来你只记一个数。您希望如何仅通过一次计数来跟踪多个值?
  • 我建议添加一个名为 countStrings[] 的新字符串数组,其中元素 0 跟踪小于 1 的值的计数,元素 1 跟踪小于 2 的值的计数,依此类推.在每个if 条件的代码中,您将在数组中的相应元素上附加一个星号。例如,如果array[i] &gt;= 3 &amp;&amp; array[i] &lt; 4,您将执行语句countStrings[3] += "*";
  • 您可以使用Math.floor 函数进一步简化代码,并去掉所有if-then-else 语句。
  • 类似countStrings[Math.floor(array[i])) += "*";
  • Math.floor 只是将双精度数转换为下一个最小整数。所以Math.floor(3.5) 将是 3。

标签: java arrays loops methods histogram


【解决方案1】:

此解决方案使用(int) Math.floor(array[i]) 选择放置双精度值的括号,从而摆脱多个 if-then-else 语句。我还使用 StringBuilder 而不是 String 来使星号的重复连接更有效。

public static void drawHistogram(double[] array) {

    StringBuilder histoGram[] = new StringBuilder[11];
    for (int i = 0; i < histoGram.length; i++) {
        histoGram[i] = new StringBuilder();
    }

    for (int i = 0; i < array.length; i++) {
        int bracket = (int) Math.floor(array[i]);
        if (bracket >= 0 && bracket < histoGram.length) {
            histoGram[bracket].append("*");
        }
    }
    for (int j = 0; j < 11; j++) {
        System.out.format("%02d: %s\n", j, histoGram[j].toString());
    }
}

测试main方法:

public static void main(String args[]) {
    double[] testValues = new double[100];
    for (int i = 0; i < 100; i++) {
        testValues[i] = Math.random() * 11.0;
    }
    drawHistogram(testValues);
}

样本输出:

00: *******
01: ********
02: ***********
03: ************
04: ********
05: **********
06: *******
07: ********
08: **********
09: ************
10: *******

【讨论】:

    【解决方案2】:
    public static void drawHistogram(double[] array) {
    
            String count[] = new String[array.length];
    
            for (int i = 0; i < array.length; i++) {
                if (array[i] >= 0 && array[i] < 1) {
                    count[0] = "*";
                } else if (array[i] >= 1 && array[i] < 2) {
                    count[1] = "*";
                } else if (array[i] >= 2 && array[i] < 3) {
                    count[2] = "*";
                } else if (array[i] >= 3 && array[i] < 4) {
                    count[3] = "*";
                } else if (array[i] >= 4 && array[i] < 5) {
                    count[4] = "*";
                } else if (array[i] >= 5 && array[i] < 6) {
                    count[5] = "*";
                } else if (array[i] >= 6 && array[i] < 7) {
                    count[6] = "*";
                } else if (array[i] >= 2 && array[i] < 8) {
                    count[7] = "*";
                } else if (array[i] >= 2 && array[i] < 9) {
                    count[8] = "*";
                } else if (array[i] >= 9 && array[i] < 10) {
                    count[9] = "*";
                } else if (array[i] >= 10 && array[i] < 11) {
                    count[10] = "*";
                }
            }
            for (int j = 0; j <= 10; j++) {
                System.out.print(j + count[j]);
                System.out.println();
            }
    }
    

    【讨论】:

    • 感谢您的回复
    【解决方案3】:

    您似乎只使用一个变量来计算此方法中数字的出现次数。这会导致您的程序显示 0 出现 9 次,其余数字出现 0 次。我同意 cmets 中的用户 David Choweller 的观点,他建议您可以使用数组来解决这个问题。但是,另一种解决方案可能是 HashMap,您将数字存储为键,将要打印的字符串存储为值。然后,您可以像当前一样在末尾的数字中使用循环,并打印出与它们关联的值。

    【讨论】:

    • 我只是想说明数组解决方案可能更快更高效,但是我想分享一下我看到这个问题时首先想到的解决方案。
    • 感谢@UnknowableIneffible 的反馈
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-08
    • 2018-04-10
    • 2016-10-26
    • 2014-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多