Java, удаление избыточных элементов в массиве - PullRequest
0 голосов
/ 01 сентября 2018

Для этой конкретной проблемы я пытаюсь удалить избыточные элементы в отсортированном массиве и заменить их все на 0 в конце массива. Например, если бы у меня был массив, состоящий из элементов int

1,3,3,4,4,5,6,6,7

Мой выходной массив должен быть

1,3,4,5,6,7,0,0,0

Моя первая попытка решить проблему состояла в том, чтобы создать модуль подкачки, чтобы после удаления элементов сдвинуть все 0 в конец списка, но, похоже, нули не будут сдвигать нули в конец списка. Вот мой код.

 public void implode(int[] ary) 
    {
        int swapper = -1;

        int[] newARY = new int[ary.length];
        int current = -1;

        for (int i = 0; i < ary.length; i++)
        {
            if (current != ary[i])
            {
            newARY[i] = ary[i];
            current = ary[i];
            }

        }

        for (int i = 0; i < ary.length; i++)
        {
            if (ary[i] == 0)
            {
                if (ary[i + 1] != 0)
                {
                    swapper = ary[i + 1];
                    ary[i] = swapper;
                    ary[i + 1] = 0;
                }

            }

        }

        ary = newARY;
        for (int i = 0; i < newARY.length; i++)
        {
            System.out.print(newARY[i] + " ");
        }

    }

Массив, с которым я тестирую это,

 int[] aryIn2 = {1, 1, 2, 3, 4, 4, 5, 6};

Однако при выводе развернутого массива я получаю этот.

1 0 2 3 4 0 5 6

Что-то мне не хватает?

Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 01 сентября 2018

Два вопроса с вашим кодом, которые я наблюдал.

1) Ваша логика подкачки выполняет перестановку в массиве, отличном от того, в котором вы выполняли модификацию ранее

2) Вы должны иметь эту логику в виде пузырьков, то есть цикл внутри цикла

Ниже приведен рабочий модифицированный пример кода вашего метода. Я изменил только вторую логику цикла for

public void implode(int[] ary) {
    int swapper = -1;

    int[] newARY = new int[ary.length];
    int current = -1;

    for (int i = 0; i < ary.length; i++) {
        if (current != ary[i]) {
            newARY[i] = ary[i];
            current = ary[i];
        }

    }

    for (int i = 0; i < newARY.length - 1; i++) {
        if (newARY[i] == 0 && newARY[i + 1] != 0) {
            for (int j = i; (j + 1) < newARY.length; j++) {
                swapper = newARY[j + 1];
                newARY[j] = swapper;
                newARY[j + 1] = 0;
            }
        }
    }

    for (int i = 0; i < newARY.length; i++) {
        System.out.print(newARY[i] + " ");
    }

}
0 голосов
/ 01 сентября 2018

не является решением вашей проблемы, но использование (если возможно) потоков Java может сократить ваш путь:

int[] arr = {1,3,3,4,4,5,6,6,7};

// distinct
List<Integer> list = Arrays.stream(arr).distinct().boxed().collect(Collectors.toList());

// pad with zero's
while(list.size() < arr.length) {
    list.add(0);
}

// display
System.out.println(list.stream().map(String::valueOf).collect(Collectors.joining(",")));

выдаст

1,3,4,5,6,7,0,0,0
0 голосов
/ 01 сентября 2018

В этом первом цикле:

for (int i = 0; i < ary.length; i++) {
    if (current != ary[i]) {
        newARY[i] = ary[i];
        current = ary[i];
    }
}

Вы заполняете newARY элементами в ary с дублированным значением, которое превращается в 0:

newARY: 1 0 2 3 4 0 5 6

Однако во втором цикле:

 for (int i = 0; i < ary.length; i++)
    {
        if (ary[i] == 0)
        {
            if (ary[i + 1] != 0)
            {
                swapper = ary[i + 1];
                ary[i] = swapper;
                ary[i + 1] = 0;
            }

        }

    }

Вы изменяете свой исходный массив ary. Таким образом, newARY не обновляется.

Однако ваша попытка выдвинуть 0 в конец массива также не удастся, если существует более двух последовательных нулей. И оно также уязвимо для ArrayOutOfBoundIndexException, так как вы пытаетесь читать ary[i+1] без ограничения на i

Один простой и прямой способ поместить 0 в конец массива - создать новый массив с элементами, отличными от 0, и заполнить 0 позже:

int[] result = new int[ary.lenght];
int resultIndex = 0;
for (int i = 0; i < newARY.length; i++) {
    if (newARY[i] != 0) {
        result[resultIndex++] = newAry[i];
    }
}
for (int i = resultIndex; i < newARY.length; i++) {
    result[i] = 0;
}

// Print result array

Подсказка: используя вышеуказанную стратегию, вы можете упростить свой код. Нет необходимости создавать немедленный массив newARY. Просто зациклите исходный массив, вставьте уникальные элементы в результирующий массив, затем заполните любой оставшийся слот нулями.

...