Изменение кода 2D ArrayList на 2D-массив

Я нашел этот код онлайн, и он хорошо работает, чтобы переставить через данный массив и вернуть все возможные комбинации чисел. Кто-нибудь знает, как изменить этот код, чтобы вместо этого включить 2D-массив?

public static ArrayList < ArrayList < Integer >> permute ( int [] numbers ) { ArrayList < ArrayList < Integer >> permutations = new ArrayList < ArrayList < Integer >> ();   
      

    перестановки . add ( новый ArrayList < Integer > ()); 

    для ( Int я = 0 ; я < число . длины ; я ++ ) {     

        ArrayList < ArrayList < Integer >> current = new ArrayList < ArrayList < Integer >> (); for ( ArrayList < Integer > p : перестановки ) { for ( int j = 0 , n = p . size () + 1 ; j < n ; j ++ ) { ArrayList < Integer > temp = new ArrayList < Integer > ( p ); 
                темп . add ( j , numbers [ i ]); 
                текущий . add ( temp ); } } 
        permutations = new ArrayList < ArrayList < Integer >> ( текущий ); }  
           
                   
                  
            
          
    

    возвратные перестановки ; } ava prettyprint prettyprinted ">
  public static int[][] permute(int[] numbers){
    int[][] permutations = new int[24][4];
    permutations[0] = new int[4];
    for ( int i = 0; i < numbers.length; i++ ) {
        int[][] current = new int[24][4];
        for ( int[] permutation : permutations ) {
            for ( int j = 0; j < permutation.length; j++ ) {
                permutation[j] = numbers[i];
                int[] temp = new int[4];
                current[i] = temp;

            }

        }
        permutations = current;
    }
    return permutations;

}  

Это то, что у меня есть atArrayListted:

temp.add(j, numbers[i]);

Однако это возвращает все нули. Я выбрал 24 и 4, потому что это размер 2D-массива, который мне нужен. благодаря

java,arrays,arraylist,

1

Ответов: 2


0 принят

Это не так просто. Исходный код использует более динамичное поведение j, поэтому потребуется немного ручного кодирования. В вашем коде есть много правильных мыслей. Я попытался написать объяснение проблем, которые я видел, но он стал слишком длинным, поэтому я решил изменить ваш код.

Оригинал - самая сложная задача, связанная с массивами, поскольку она заставляет элементы, находящиеся справа от положения, располагаются справа. В моей версии я создаю массив temp только один раз в среднем цикле и перемешиваю один элемент за раз в самом внутреннем цикле.public static int[][] permute(int[] numbers) { // Follow the original here and create an array of just 1 array of length 0 int[][] permutations = new int[1][0]; for (int i = 0; i < numbers.length; i++) { // insert numbers[i] into each possible position in each array already in permutations. // create array with enough room: when before we had permutations.length arrays, we will now need: int[][] current = new int[(permutations[0].length + 1) * permutations.length][]; int count = 0; // number of new permutations in current for (int[] permutation : permutations) { // insert numbers[i] into each of the permutation.length + 1 possible positions of permutation. // to avoid too much shuffling, create a temp array // and use it for all new permutations made from permutation. int[] temp = Arrays.copyOf(permutation, permutation.length + 1); for (int j = permutation.length; j > 0; j--) { temp[j] = numbers[i]; // remember to make a copy of the temp array current[count] = temp.clone(); count++; // move element to make room for numbers[i] at next position to the left temp[j] = temp[j - 1]; } temp[0] = numbers[i]; current[count] = temp.clone(); count++; } assert count == current.length : "" + count + " != " + current.length; permutations = current; } return permutations; }j

permutation

Мой трюк с массивом temp означает, что я не получаю temps в том же порядке, что и в коде origianl. Если это требование, вы можете скопировать permutationв tempисходный код с индексом 1 и перетасовать противоположный путь в цикле. System.arraycopy()может выполнить первоначальное копирование.


0

Проблема здесь в том, что вам действительно нужно правильно реализовать версию массива ArrayList.add(int,value)команды. Скажем, вы делаете System.arraycopy () и нажимаете все значения после j, вниз по одному, а затем вставляете значение в j. В настоящее время вы устанавливаете значение. Но это перезаписывает значение перестановки [j], которое должно быть уже перенесено на перестановки [j + 1].

Итак, где вы делаете:

permutation[j] = numbers[i];    

Должен быть:

System.arraycopy(permutation,j, permutations, j+1, permutations.length -j);
permutation[j] = numbers[i];

Поскольку ArrayList.add (int, value) делает это. Вы в основном ошибочно реализовали его как .set ().

Хотя лично я бы отказался от кода и пошел с чем-то, чтобы динамически сделать эти ценности «на лету». Еще несколько значений, и вы говорите что-то непомерно важное в отношении памяти. Нетрудно найти n-й индекс перестановки. Даже без выделения какой-либо памяти. (хотя вам нужна копия массива, если вы собираетесь играть с такими вещами без каких-либо странностей).

public static int[] permute(int[] values, long index) {
    int[] returnvalues = Arrays.copyOf(values,values.length);
    if (permutation(returnvalues, index)) return returnvalues;
    else return null;

}
public static boolean permutation(int[] values, long index) {
    return permutation(values, values.length, index);
}

private static boolean permutation(int[] values, int n, long index) {
    if ((index == 0) || (n == 0))  return (index == 0);
    int v = n-(int)(index % n);
    int temp = values[n];
    values[n] = values[v];
    values[v] = temp;
    return permutation(values,n-1,index/n);
}
Java, массивы, ArrayList,
Похожие вопросы