Я пытаюсь, учитывая некоторый ArrayList из целых чисел, создать все перестановки этого списка. Я хочу сохранить каждую перестановку (сам ArrayList) в более крупном массиве ArrayList из ArrayLists. Я могу найти перестановки и распечатать каждый на консоли без проблем. Я не нашел способ успешно добавить их в список. Моя текущая попытка показана ниже.
//myList is a field that I need to use elsewhere
//a is the ArrayList of Integers
//initially, n is a.size()
private static void perm2(ArrayList<ArrayList<Integer>> myList,
ArrayList<Integer> a, int n)
{
for (int i = 0; i < n; i++)
{
swap(a, i, n-1);
perm2(where, a, n-1);
swap(a, i, n-1);
}
if (n == 1)
{
System.out.println(a.toString());
myList.add(a);
return;
}
}
Вот результат, указанный [0, 1, 2]:
[1, 2, 0]
[2, 1, 0]
[2, 0, 1]
[0, 2, 1]
[1, 0, 2]
[0, 1, 2]
[[0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]]
Код печати отправляет правильную информацию на консоль, поэтому почему он не добавляет правильную вещь сразу после? Если это нехороший способ пойти по этому пути, в каком направлении я должен смотреть? В конечном счете, это индексы для извлечения данных из списка в каждом порядке.
Заранее спасибо.
Следует отметить, что список входных данных может иметь произвольную длину в рамках разумных вычислительных возможностей.
EDIT: контроль с моей стороны. Здесь код подкачки:
private static void swap(ArrayList<Integer> list, int a, int b)
{
T temp = list.get(a);
list.set(a, list.get(b));
list.set(b, temp);
}
Вы не показали нам swap
, но я предполагаю, что он изменяет список на месте. Список списков затем содержит несколько ссылок на один и тот же базовый список, который находится в конечном перестановленном состоянии. В принципе, вы поместили изменяемый объект в список, а затем изменили его, ожидая, что он будет находиться в состоянии, в котором он был, когда вы впервые добавили его в список.
Один из способов исправить это - сделать защитную копию списка в момент его добавления:
myArray.add(new ArrayList<Integer>(a));
(Также вы вызываете переменную myArray
и говорите "добавьте их в массив", но myArray
- это List
и вы добавляете вещи в список. Я был немного смущен, когда впервые прочитал ваш вопрос. к списку в виде массива.)
Вы всегда сохраняете тот же список в списке списков. Затем вы меняете свои элементы и храните их снова. Таким образом, вы получаете N ссылок на один и тот же список. Вам необходимо сделать копию списка, прежде чем хранить его в списке списков:
myArray.add(new ArrayList<>(a));
Каждый раз, когда вы вызываете метод 'add' на myArray, элементы 'a' не копируются. myArray проведет ссылку только на 'a'. Поскольку ссылка всегда одна и та же, последнее состояние элемента "a" будет напечатано.
Попробуйте распечатать содержимое myArray сразу после myArray.add(a), чтобы понять, что я имею в виду.
Вам нужно создать новый экземпляр ArrayList, чтобы избежать этой проблемы.