1

如果一个数组是这样填充的:

for (int i = 0; i < rand.length; i++) {
    rand[i] = (int) Math.round(Math.random() * 1000000) + 1;
}

然后使用 Arrays.sort 或任何排序算法进行排序,如果有的话

int sum = 0;
    for(int i = 0; i < rand.length;i++) {
        if (i % 2 == 0) {
            sum += rand[i] + rand[rand.length - 1 -i];
        }
        else
            sum -= rand[i] + rand[rand.length - 1 - i];
    }
    System.out.println("\n");
    System.out.println(sum);

那么总和将永远为零。在我测试过一百次左右的情况下,这已证明是正确的。尝试任何范围,任何数组长度。

我无法想象伪随机性真的会有那么大的缺陷。这里发生了什么?

4

2 回答 2

8

随机数生成器产生的数字并不重要。只要您的数组具有偶数长度,您使用该函数计算的总和将始终为零。

让我们用数学方法证明这一点。假设我们有一个包含四个元素的数组:[A, B, C, D]. (值无关紧要,我会证明这一点。)

对于循环中的每次:

  • i = 0: sum += A + D. 现在总和A + D
  • i = 1: sum -= B + C. 现在总和(A + D) - (B + C)
  • i = 2: sum += C + B. 现在总和(A + D) - (B + C) + (C + B)
  • i = 3: sum -= D + A. 现在总和(A + D) - (B + C) + (C + B) - (D + A)

如果我们扩展它,我们得到A + D - B - C + C + B - D - A. 一切都抵消了;结果为零。总是。

同样的原则适用于任何偶数长度的数组。每个数字最终都会被加两次并被减去两次,所以这一切都被抵消了。

于 2013-06-22T15:43:51.857 回答
4

如果长度是偶数,则将所有数字相加一次,然后将所有数字相减一次——当然,结果为 0。

示例length==6

/*i==0*/  sum += rand[0] + rand[5];
/*i==1*/  sum -= rand[1] + rand[4];
/*i==2*/  sum += rand[2] + rand[3];
/*i==3*/  sum -= rand[3] + rand[2];
/*i==4*/  sum += rand[4] + rand[1];
/*i==5*/  sum -= rand[5] + rand[0];

你试过不均匀的长度吗?

于 2013-06-22T15:43:03.830 回答