После внесения перестановок, как мне добавить их в массив? [Ява]

1

Я пытаюсь, учитывая некоторый 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);
}
  • 0
    что делает функция подкачки? Можете ли вы предоставить код?
  • 0
    обновлено, спасибо за указание на это.
Теги:
arrays
permutation

3 ответа

2
Лучший ответ

Вы не показали нам swap, но я предполагаю, что он изменяет список на месте. Список списков затем содержит несколько ссылок на один и тот же базовый список, который находится в конечном перестановленном состоянии. В принципе, вы поместили изменяемый объект в список, а затем изменили его, ожидая, что он будет находиться в состоянии, в котором он был, когда вы впервые добавили его в список.

Один из способов исправить это - сделать защитную копию списка в момент его добавления:

myArray.add(new ArrayList<Integer>(a));

(Также вы вызываете переменную myArray и говорите "добавьте их в массив", но myArray - это List и вы добавляете вещи в список. Я был немного смущен, когда впервые прочитал ваш вопрос. к списку в виде массива.)

  • 1
    Я обновил свой пост, добавив в него своп, а также изменил ссылки на мой ArrayList с «массива» на «список» для ясности другим читателям. В любом случае, ваше решение сработало отлично. Я ценю это.
5

Вы всегда сохраняете тот же список в списке списков. Затем вы меняете свои элементы и храните их снова. Таким образом, вы получаете N ссылок на один и тот же список. Вам необходимо сделать копию списка, прежде чем хранить его в списке списков:

myArray.add(new ArrayList<>(a));
  • 0
    Это решение, которое я искал. Спасибо!
0

Каждый раз, когда вы вызываете метод 'add' на myArray, элементы 'a' не копируются. myArray проведет ссылку только на 'a'. Поскольку ссылка всегда одна и та же, последнее состояние элемента "a" будет напечатано.

Попробуйте распечатать содержимое myArray сразу после myArray.add(a), чтобы понять, что я имею в виду.

Вам нужно создать новый экземпляр ArrayList, чтобы избежать этой проблемы.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню