Добавление ArrayList в HashSet в Java - PullRequest
1 голос
/ 01 мая 2020

Мне было поручено реализовать алгоритм перебора для вывода всех перестановок целых чисел [1, 2, ..., n] для некоторого n. Однако у меня, кажется, есть некоторая проблема с добавлением объектов ArrayList в HashSet:

static Set<List<Integer>> allPermutations(int n){
        if(n<=0){throw new IllegalArgumentException();}

        List<Integer> thisPermutation = new ArrayList<Integer>();
        for(int i=1; i<=n; i++){
            thisPermutation.add(i);
        }
        Set<List<Integer>> allPermutations = new HashSet<List<Integer>>();

        while(true){
            allPermutations.add(thisPermutation);
            thisPermutation = nextPermutation(thisPermutation);
            if(thisPermutation == null){break;}
        }
        return allPermutations;
}

Я обнаружил, что последовательные вызовы 'nextPermutation' действительно находят все перестановки, но я не понимаю, что происходит, когда я добавляю перестановки к HashSet 'allPermutations'. Вывод, который я получаю при работе с n = 3, таков:

[[3, 2, 1, 1, 2, 1, 1, 3, 1, 2], [3, 2, 1], [3, 2, 1, 1, 2, 1, 1], [3, 2, 1, 1], [3, 2, 1, 1, 2, 1, 1, 3, 1], [ 3, 2, 1, 1, 2, 1]]

Я новичок в Java и буду признателен за любую помощь.

Редактировать: Вот функция nextPermutation:

static List<Integer> nextPermutation(List<Integer> sequence){
        int i = sequence.size() - 1;
        while(sequence.get(i) < sequence.get(i-1)){
            i -= 1;
            if(i == 0){
                return null;
            }
        }
        int j = i;
        while(j != sequence.size()-1 && sequence.get(j+1) > sequence.get(i-1)){
            j += 1;
        }
        int tempVal = sequence.get(i-1);
        sequence.set(i-1, sequence.get(j));
        sequence.set(j, tempVal);

        List<Integer> reversed = new ArrayList<Integer>();
        for(int k = sequence.size()-1; k>=i; k--){
            reversed.add(sequence.get(k));
        }

        List<Integer> next = sequence.subList(0, i);
        next.addAll(reversed);

        return next;
}

1 Ответ

2 голосов
/ 01 мая 2020

List<Integer> sequence передается методу nextPermutation и изменяется внутри метода: sequence.set(j, tempVal);. Таким образом, исходная перестановка изменяется каждый раз, когда вызывается метод nextPermutation ( Вызов с общим доступом ).

Однако вы можете легко адаптировать свой код для создания копии списка внутри метод:

static List<Integer> nextPermutation(final List<Integer> s) {
    List<Integer> sequence = new ArrayList<>(s);
    int i = sequence.size() - 1; 
    // ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...