Удалить элемент массива и сдвинуть оставшиеся - PullRequest
18 голосов
/ 19 мая 2009

Как удалить элемент массива и сдвинуть оставшиеся элементы вниз. Итак, если у меня есть массив,

array[]={1,2,3,4,5} 

и хочу удалить 3 и сдвинуть остальные, чтобы у меня было,

array[]={1,2,4,5}

Как бы я поступил об этом при наименьшем количестве кода?

Ответы [ 8 ]

29 голосов
/ 19 мая 2009

Вам просто нужно переписать то, что вы удаляете, следующим значением в массиве, распространить это изменение, а затем иметь в виду, где новый конец:

int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};

// delete 3 (index 2)
for (int i = 2; i < 8; ++i)
    array[i] = array[i + 1]; // copy next element left

Теперь ваш массив {1, 2, 4, 5, 6, 7, 8, 9, 9}. Вы не можете удалить лишние 9, так как это массив статического размера, вы просто должны его игнорировать. Это можно сделать с помощью std::copy:

std::copy(array + 3, // copy everything starting here
          array + 9, // and ending here, not including it,
          array + 2) // to this destination

В C ++ 11 вместо использования можно использовать std::move (перегрузка алгоритма, а не перегрузка утилиты).

В более общем случае используйте std::remove для удаления элементов, соответствующих значению:

// remove *all* 3's, return new ending (remaining elements unspecified)
auto arrayEnd = std::remove(std::begin(array), std::end(array), 3);

В более общем смысле, есть std::remove_if.

Обратите внимание, что использование std::vector<int> может быть более уместным здесь, так как это "истинный" динамически распределяемый массив изменения размера. (В том смысле, что запрос его size() отражает удаленные элементы.)

21 голосов
/ 19 мая 2009

Вы можете использовать memmove(), но вы должны сами следить за размером массива:

size_t array_size = 5;
int array[5] = {1, 2, 3, 4, 5};

// delete element at index 2
memmove(array + 2, array + 3, (array_size - 2 - 1) * sizeof(int));
array_size--;

Однако в C ++ было бы лучше использовать std::vector:

std::vector<int> array;
// initialize array...

// delete element at index 2
array.erase(array.begin() + 2);
10 голосов
/ 19 мая 2009

std :: copy выполняет работу, касающуюся перемещения элементов:

 #include <algorithm>

 std::copy(array+3, array+5, array+2);

Обратите внимание, что предварительным условием для копирования является то, что место назначения не должно находиться в исходном диапазоне. Допустимо перекрытие диапазонов.

Кроме того, из-за того, как массивы работают в C ++, это не «укорачивает» массив. Это просто перемещает элементы вокруг него. Нет никакого способа изменить размер массива, но если вы используете отдельное целое число для отслеживания его «размера», означающего размер интересующей вас части, то вы, конечно, можете уменьшить это.

Таким образом, массив, с которым вы будете работать, будет выглядеть так, как если бы он был инициализирован:

int array[] = {1,2,4,5,5};
5 голосов
/ 19 мая 2009

Вы не можете достичь того, что вы хотите с массивами. Вместо этого используйте векторы и прочитайте об алгоритме std :: remove. Что-то вроде:

std::remove(array, array+5, 3)

будет работать с вашим массивом, но не будет его сокращать (почему - потому что это невозможно). С векторами это было бы что-то вроде

v.erase(std::remove(v.begin(), v.end(), 3), v.end())
3 голосов
/ 19 мая 2009

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

1 голос
/ 06 февраля 2014

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

1 голос
/ 28 марта 2013

Если вас больше всего беспокоит размер кода и / или производительность (также для анализа WCET, если он вам нужен), я думаю, что это, вероятно, будет одним из наиболее прозрачных решений (для поиска и удаления элементов):

unsigned int l=0, removed=0;

for( unsigned int i=0; i<count; i++ ) {
    if( array[i] != to_remove )
        array[l++] = array[i];
    else
        removed++;
}

count -= removed;
0 голосов
/ 11 января 2019

Programming Hub случайным образом предоставил фрагмент кода, который на самом деле действительно уменьшает длину массива

for (i = position_to_remove; i < length_of_array; ++i) {
        inputarray[i] = inputarray[i + 1];
}

Не уверен, что это поведение было добавлено только позже. Это делает трюк, хотя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...