java - 高尔顿箱;打印直方图

标签 java arrays loops

嘿伙计们,我正在编写一个家庭作业程序来显示高尔顿盒子中球的路径

/image/Ltypc.png

到目前为止,我的程序会选择您想要掉落的球数以及盒子底部的插槽数量,然后向您显示球所经过的随机路径。

我遇到的问题是创建一个描述最终结果的直方图。 我发现的一个重要信息是,每次球落到右侧时,它都会移动一个位置。因此,如果打印语句是 LRLRLR,由于 3 个 R,它将位于第三个槽中。

它可以打印的随机直方图示例:

/image/zCotG.png

public class Set_8_P6_21 {

public static void main(String[] args) {

    // Declaring variables and calling scanner
    int balls, slots;

    System.out.println("Enter the amount of balls to drop: ");

    Scanner input = new Scanner(System.in);
    balls = input.nextInt();

    System.out.println("Enter the amount of slots: ");
    slots = input.nextInt();


    char[] arrayslot = new char[slots-1];
    int[] arraypattern = new int[slots-1];

    // Nested loop that runs the amount of balls through the machine, and through the amount of slots. 
    for (int i = 0; i < balls; i++) {
        System.out.println();

        for (int j = 0; j < slots-1; j++) {

            double k = Math.random();

            if (k < 0.5) {
                arrayslot[j] = 'L' ;
                arraypattern[j] = 1; // This is where I am trying to make my histogram
            }

            else if (k >= 0.5) {
                arrayslot[j] = 'R';
                arraypattern[j] = 0; // This is where I am trying to make my histogram
            }

            System.out.print(arrayslot[j]);

        }

    }}}

如果有人知道如何使用来自循环的信息进行打印,这将非常有帮助,感谢您花时间阅读本文。

最佳答案

首先,您实际上没有必要保留数组arrayslot,因为您立即打印了该数组元素,并且之后无需对其执行任何操作。所以你可以只打印字符:

            if ( k < 0.5 ) {
                System.out.print("L");
            } else {
                System.out.print("R");
            }

正如您所注意到的,也不需要 else if。 k 要么小于 0.5,要么大于 0.5。所以你可以只使用else

为了找出球将落入哪个槽,您需要计算 R。为此,您只需拥有一个在每个球模拟开始时获取 0 的 int,然后在上面滚动“R”时将其添加到该值。所以你的循环扩展到:

    for (int i = 0; i < balls; i++) {
        int ballSlot = 0;

        for (int j = 0; j < slots - 1; j++) {

            double k = Math.random();

            if ( k < 0.5 ) {
                System.out.print("L");
            } else {
                System.out.print("R");
                ballSlot++; 
            }

        }

        System.out.println();
    }

但是,当然,如果我们这样做,该值就不会去任何地方,并且在完成对球的模拟后我们会丢失它。你想要做的是保留一个数组,其中保存我们点击每个槽的次数。因此,在每个球的模拟结束时,当我们知道它落入哪个槽时,我们将给给定的槽加 1。如果我们点击同一个槽 3 次,数组中的该位置就会有 3 个:

    int[] frequencies = new int[slots];

    // Nested loop that runs the amount of balls through the machine, and
    // through the amount of slots.
    for (int i = 0; i < balls; i++) {
        int ballSlot = 0;

        for (int j = 0; j < slots - 1; j++) {

            double k = Math.random();

            if ( k < 0.5 ) {
                System.out.print("L");
            } else {
                System.out.print("R");
                ballSlot++; 
            }

        }

        frequencies[ballSlot]++;
        System.out.println();
    }

现在,为了正确打印直方图,您必须从最高的列开始,一直向下,直到到达直方图的“底部”,为每个列打印一个 O具有该频率的球的槽。例如,如果插槽 4 和 5 中有 3 个球,插槽 2 中有 1 个球,则从最高频率 3 开始:

  • 对于频率 3,在第 4 和第 5 个位置打印 O
  • 对于频率 2,在此高度没有新位置,但您必须再次在第 4 和第 5 处打印 O,否则您将仅在以下位置打印 O列的顶部,而不是整个高度。
  • 对于频率 1,您可以在第 2、4 和 5 个位置打印 O

因此,为了做到这一点,我们必须首先找出最高频率。您可以扫描该数组,但实际上,您可以在进行模拟时计算它:

    int[] frequencies = new int[slots];
    int maxFrequency = 0;

    // Nested loop that runs the amount of balls through the machine, and
    // through the amount of slots.
    for (int i = 0; i < balls; i++) {
        int ballSlot = 0;

        for (int j = 0; j < slots - 1; j++) {

            double k = Math.random();

            if ( k < 0.5 ) {
                System.out.print("L");
            } else {
                System.out.print("R");
                ballSlot++; 
            }

        }

        frequencies[ballSlot]++;
        if ( frequencies[ballSlot] > maxFrequency ) {
            maxFrequency = frequencies[ballSlot];
        }
        System.out.println();
    }

如您所见,如果任何频率大于当前的 maxFrequency,我们会将其保留为新的 maxFrequency

现在,打印直方图:

    for ( int i = maxFrequency; i > 0; i-- ) {
        for ( int j = 0; j < slots; j++ ) {
            if ( frequencies[j] >= i ) {
                System.out.print( "O");
            } else {
                System.out.print( " ");
            }
        }
        System.out.println();
    }

对于这个级别没有球的每个位置,我们打印一个空格。对于有球的位置,我们打印 O

变量i表示我们正在绘制的直方图的当前级别高度。因此,条件 if (Frequency[j] >= i) 的意思是 如果在这个位置,我们至少拥有与当前高度一样多的球

就是这样。在模拟循环之前和直方图循环之前添加一个 System.out.println() 到输入、模拟和直方图之间的空间,然后就完成了。

关于java - 高尔顿箱;打印直方图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27112226/

相关文章:

java - 没有异常困惑的文件 I/O

java - 复制并重定向 System.err 流

arrays - 如何在 Swift 中转换字符串?

javascript - 轻松循环遍历 json api 数组 jquery

python - 使用Python OpenCV在循环中进行图像平铺

c - 验证循环

javascript - Jquery Queue() Each() 与延迟()

java - JSF 语言环境异常

java - 当输入错误的详细信息时,CardInputWidget 不会产生动画

python - 将excel列提取到python数组中