关于java:随机“摇动”一个数组以分配新的随机点

Randomly “shaking” an array to assign new random spots

我想做的是拿我的阵列硬币[]。 并且基本上将每个硬币重新排列到不同的位置。 这就是我到目前为止所拥有的。 当我这样做时,没有任何反应。 意味着所有的值都保持不变。 除了最后一个。 那个改变了。

1
2
3
4
5
6
7
8
9
10
11
12
public void shake()
{
    for (int i = 0; i < coins.length; i++)
    {
        int index = Coin.RANDOM.nextInt(coins.length);
        Coin temp = coins[index];
        coins[index] = coins[i];
        coins[i] = temp;

        System.out.print(coins[i] +",");
    }
}

我像这样实例化随机:

1
2
public static long SEED = System.currentTimeMillis();
public static Random RANDOM = new Random(SEED);


请注意这一行

1
System.out.print(coins[swap] +",");

显示已移动(交换)的硬币。也许你正在考虑在i索引处显示新硬币:coins[i](无论如何这都不正确,因为已经显示的硬币仍然可以在下一次迭代中交换)。可能最好创建第二个for循环来显示最终的硬币值。

但这不仅仅是问题。要随机混洗数组,您应该使用Fisher-Yates算法,该算法与您的方法略有不同。您可以在SO上找到此算法的Java实现。

如果您使用List而不是Coin[](列表而不是数组),则可以使用Collections.shuffle方法并确保算法正确并且您将始终获得随机结果。


你为什么不使用收藏品?将随机索引分配给数组或ArrayList中的每个值非常简单。

1
2
Collections.shuffle(coins);//if coins is array
Collections.shuffle(Arrays.asList(coins));//if coins is an ArrayList


当您使用swap作为索引时,您将使用该索引交换当前值,您可以编辑随机数生成器以生成特定范围之间的随机数(比如0 - coins.length),然后您可以将实现更改为这样的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void shake()
{

    Coin temp;

    for (int i = 0; i < coins.length; i++)
    {
        //int swap = Coin.RANDOM.nextInt(coins.length);
        temp = coins[swap];
        coins[swap] = coins[i];
        coins[i] = temp;

        System.out.print(coins[i] +",");
    }
}

对于代码中的注释行,请检查此以更新随机数生成器以生成两个值之间的数字。然后每次在i+1 - coins.length之间生成交换(索引)并继续此操作,直到完全耗尽阵列。这可确保您不会在索引处交换已显示的值。但我并不完全相信这确实是一个随机的随机播放,因为在循环开始时你有更多的交换索引选择,那么你将在循环后的某个时间,并且震动不是完全随机的。此解决方案仅在您想要严格实施自己的摇动方法而不使用Collections.shuffle作为@Tomek提到的情况下。


您可以使用Knuth的重排算法重新排列数组,以便结果是均匀的随机排列。算法很简单,但就像一个魅力:

  • 迭代数组并在迭代中我选择0和i之间的随机整数交换
  • 交换数组[i]和数组[交换]
  • 请注意,在您的实现中,随机生成在0到11之间,这似乎不会产生良好的混乱。

    这是一个整数数组的混乱的代码示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    import java.util.Random;

    public class Test {

    public static long SEED = System.currentTimeMillis();
    public static Random RANDOM = new Random(SEED);

    public static void shuffle(int[] numbers)
    {
        for (int i = 0; i < numbers.length; i++)
        {
            int swap = RANDOM.nextInt(i + 1);
            int temp = numbers[swap];
            numbers[swap] = numbers[i];
            numbers[i] = temp;
        }

        for (int i = 0; i < numbers.length; i++) {
            System.out.print(numbers[i] +",");
        }
    }

    public static void main(String[] args) {
        shuffle(new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11});
    }

    }

    测试运行的输出是:

    1
    5, 11, 6, 1, 3, 10, 9, 2, 4, 7, 8,