如何在Java中生成列表/数组的随机排列?

时间:2019-03-28 17:32:36

标签: java arrays list data-structures permutation

我无法实现返回大小为n的随机排列的方法。我不确定我的代码有什么问题,我需要帮助找出逻辑上有问题的地方。

这是我只想编写的一个小程序,但是在可视化逻辑流程时遇到了麻烦。我尝试过更改while循环的条件,但到目前为止,我没有尝试过。我也尝试使用列表和数组列表来实现,但是当我尝试将其放入代码中时,它变得太复杂了。

有更简单的方法吗?

public static int[] derangement(int n){
    int[] arr1 = new int[n];
    int[] arr2 = new int[n];
    //second array is to keep track of which positions are 'taken' to prevent collision
    Random rand = new Random();
    int temp = -1;
    for(int i =0; i <n; i++){
        arr1[i] = i;
    }
    for(int k=0;k<n;k++){
        arr2[k] = -1;
    }
    for(int j=0;j<n;j++){
        temp = j;
        while (temp == j || arr2[j] != -1){
            temp = rand.nextInt(n); //generate a random number until it gives one that hasn't been used before
            if(arr2[temp] == -1){
                arr2[temp] = j;
            }
        }

    }
    return arr2;
}

我期望对于n = 6,输出为[2,4,1,5,3,0] 但我只得到[-1,-1,-1,-1,-1,-1]

2 个答案:

答案 0 :(得分:0)

这个想法是在一个集合中包含N个元素,然后从中选择数字,直到耗尽为止。像这样

List<Integer> temp = IntStream.range(0, 6).boxed().collect(Collectors.toList());
int[] array = new int[6];
while (temp.size() > 0) {
    int rndIndex = ThreadLocalRandom.current().nextInt(temp.size());
    array[temp.size() - 1] = temp.get(rndIndex);
    temp.remove(rndIndex);
}
System.out.println(Arrays.toString(array)); // could be [4, 5, 3, 2, 1, 0]

如果您不想使用临时列表,可以这样做,但这需要更多代码。想法是一样的。

答案 1 :(得分:-1)

在键是随机的情况下使用SortedMap怎么办?

public static int[] derangement(int n){
    Random rand = new Random();
    int[] result = new int[n];
    SortedMap<Double, Integer> map = new TreeMap<>();
    for (int i = 0; i < n; i++) {
        map.put(rand.nextDouble(), i);
    }
    int i = 0;
    for (Double key: map.keySet()) {
        result[i] = map.get(key);
        i++;
    }
    return result;
}

通过这种方式,当地图中的随机键变得有序时,您将重新排列列表。