嘿伙计们,我正在编写一个家庭作业程序来显示高尔顿盒子中球的路径
到目前为止,我的程序会选择您想要掉落的球数以及盒子底部的插槽数量,然后向您显示球所经过的随机路径。
我遇到的问题是创建一个描述最终结果的直方图。 我发现的一个重要信息是,每次球落到右侧时,它都会移动一个位置。因此,如果打印语句是 LRLRLR,由于 3 个 R,它将位于第三个槽中。
它可以打印的随机直方图示例:
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/