Сдвиг массива

Я вижу этот код в книге, что его работа - сдвиг массива.

public void arrayshift(int count) {
    synchronized (array) {
        System.arraycopy(array, count, array, 0, array.length - count);
    }
}

Теперь я запускаю этот код как вниз, но результат неправильный!

public class t2 {

static byte array[] = new byte[]{1, 2, 3, 4, 5, 6};

public void arrayshift(int count) {
    synchronized (array) {
        System.arraycopy(array, count, array, 0, array.length - count);
    }
}

public static void main(String[] args) {
    System.out.println("First array: " + Arrays.toString(array));
    new t2().arrayshift(2);
    System.out.println("After two shift is: " + Arrays.toString(array));
   }
}

Результат:

First array: [1, 2, 3, 4, 5, 6]
After two shift is: [3, 4, 5, 6, 5, 6]

4 ответа

Решение

На самом деле вращаться есть альтернативный способ, используя Collections.rotate()

В вашем случае вы можете конвертировать byte[] в Byte[], создайте список байтов и вращайте, используя Collections.rotate()

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

Ваш измененный код:

static byte array[] = new byte[] { 1, 2, 3, 4, 5, 6 };
    static List<Byte> list = new ArrayList<Byte>();

    public static void main(String[] args) {
        System.out.println("First array: " + Arrays.toString(array));
        new Rotate().arrayshift(2);
        System.out.println("After two shift is: ");
        for (Byte b : list.toArray(new Byte[list.size()]))
            System.out.print(b.byteValue() + ", ");
    }

    public void arrayshift(int count) {
        synchronized (array) {
            Byte[] byteObjects = new Byte[array.length];
            int i = 0;
            for (byte b : array)
                byteObjects[i++] = b;
            list = Arrays.asList(byteObjects);
            Collections.rotate(list, count);
        }
    }

Выход:

First array: [1, 2, 3, 4, 5, 6]
After two shift is: 
5, 6, 1, 2, 3, 4, 

Это выглядит правильно, потому что System.arraycopy принимает 5 параметров:

  1. Исходный массив: массив в вашем случае
  2. Исходная позиция: в вашем случае 2, т.е. 3-й элемент.
  3. Массив назначения: массив в вашем случае, исходный и целевой массив одинаковы в вашем случае.
  4. Позиция назначения: в вашем случае, т.е. начало массива.
  5. Длина: сколько элементов нужно переместить, 6-2=4, т.е. переместиться с 3-го, 4-го, 5-го, 6-го элемента на 0-й, 1-й, 2-й, 3-й, поэтому 5-й и 6-й не изменяются.

Похоже, что делает правильный сдвиг.

Результаты верны.

System.arraycopy(array, count, array, 0, array.length - count);

Параметры для функции:

Object src,
int srcPos,
Object dest,
int destPos,
int length

Итак, вы берете из массива [2] и далее (т.е. 3, 4, 5, 6), вы берете array.length (6) - count (2), так что 4 элемента (так [3, 4, 5, 6]) и вы копируете их в массив [0]. Это заменит первые 4 элемента массива на ваш [3,4,5,6], поэтому у вас будет [3,4,5,6,5,6]. Обратите внимание, что вы никогда ничего не делали с последними двумя значениями. Это просто сдвиг значений, а не их вращение. Если вы хотите повернуть их, вам нужно сохранить значения, которые вы собираетесь перезаписать, а затем записать их в конце.

Смотрите документы.

public static void arraycopy (Object src, int srcPos, Object dest, int destPos, int length)

Он скопирует количество элементов. В вашем коде вы копируете array.length-count, что означает, что вы копируете только 4 элемента. Последние два элемента не скопированы из источника. Таким образом, исходное значение остается.

Другие вопросы по тегам