Как мне генерировать случайное нарушение списка / массива в Java? - PullRequest
1 голос
/ 28 марта 2019

У меня проблемы с реализацией метода, который возвращает случайное отклонение размера 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;
}

Я ожидал, что выходной сигнал будет равен [2,4,1,5,3,0] для n = 6, но я просто получаю [-1, -1, -1, -1, -1, -1]

Ответы [ 2 ]

0 голосов
/ 28 марта 2019

Идея состоит в том, чтобы иметь 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]

Если вы не хотите использовать временный список, вы можете сделать это, но для этого потребуется больше кода. Идея была бы такой же.

0 голосов
/ 28 марта 2019

Как насчет использования 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;
}

Таким образом, когда случайные ключи на вашей карте упорядочиваются, вы перетасовываете список.

...