C++ 删除一个数组元素并移动剩余的元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/879603/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 17:46:43  来源:igfitidea点击:

Remove an array element and shift the remaining ones

c++arrays

提问by user103572

How do I remove an element of an array and shift the remaining elements down. So, if I have an array,

如何删除数组的元素并将其余元素向下移动。所以,如果我有一个数组,

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

and want to delete 3 and shift the rest so I have,

并想删除 3 并移动其余的所以我有,

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

How would I go about this in the least amount of code?

我将如何以最少的代码来解决这个问题?

回答by GManNickG

You just need to overwrite what you're deleting with the next value in the array, propagate that change, and then keep in mind where the new end is:

您只需要使用数组中的下一个值覆盖您要删除的内容,传播该更改,然后记住新的结尾在哪里:

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

Now your array is {1, 2, 4, 5, 6, 7, 8, 9, 9}. You cannot delete the extra 9since this is a statically-sized array, you just have to ignore it. This can be done with std::copy:

现在你的数组是{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

In C++11, use can use std::move(the algorithm overload, not the utility overload) instead.

在 C++11 中,use 可以使用std::move(算法重载,而不是实用程序重载)来代替。

More generally, use std::removeto remove elements matching a value:

更一般地,用于std::remove删除与值匹配的元素:

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

Even more generally, there is std::remove_if.

更普遍的是,有std::remove_if.

Note that the use of std::vector<int>may be more appropriate here, as its a "true" dynamically-allocated resizing array. (In the sense that asking for its size()reflects removed elements.)

请注意,这里的使用std::vector<int>可能更合适,因为它是一个“真正的”动态分配的调整大小数组。(从某种意义上说,要求它size()反映了已删除的元素。)

回答by Adam Rosenfield

You can use memmove(), but you have to keep track of the array size yourself:

您可以使用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--;

In C++, though, it would be better to use a std::vector:

但是,在 C++ 中,最好使用std::vector

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

// delete element at index 2
array.erase(array.begin() + 2);

回答by Steve Jessop

std::copy does the job as far as moving elements is concerned:

就移动元素而言, std::copy 可以完成这项工作:

 #include <algorithm>

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

Note that the precondition for copy is that the destination must not be in the source range. It's permissible for the ranges to overlap.

请注意,复制的前提是目标不能在源范围内。允许范围重叠。

Also, because of the way arrays work in C++, this doesn't "shorten" the array. It just shifts elements around within it. There is no way to change the size of an array, but if you're using a separate integer to track its "size" meaning the size of the part you care about, then you can of course decrement that.

此外,由于数组在 C++ 中的工作方式,这不会“缩短”数组。它只是在其中移动元素。没有办法改变数组的大小,但是如果你使用一个单独的整数来跟踪它的“大小”,这意味着你关心的部分的大小,那么你当然可以减少它。

So, the array you'll end up with will be as if it were initialized with:

所以,你最终得到的数组就好像它是用以下方法初始化的一样:

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

回答by zvrba

You can't achieve what you want with arrays. Use vectors instead, and read about the std::remove algorithm. Something like:

你不能用数组实现你想要的。改用向量,并阅读 std::remove 算法。就像是:

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

will work on your array, but it will not shorten it (why -- because it's impossible). With vectors, it'd be something like

将在您的阵列上工作,但不会缩短它(为什么 - 因为这是不可能的)。使用向量,它会像

v.erase(std::remove(v.begin(), v.end(), 3), v.end())

回答by PiNoYBoY82

Depending on your requirements, you may want to use stl lists for these types of operations. You can iterate through your list until you find the element, and erase the element. If you can't use lists, then you'll have to shift everything yourself, either by some sort of stl algorithm or manually.

根据您的要求,您可能希望将 stl 列表用于这些类型的操作。您可以遍历列表直到找到该元素,然后删除该元素。如果您不能使用列表,那么您必须自己移动所有内容,通过某种 stl 算法或手动进行。

回答by Yuri Feldman

Just so it be noted: If the requirement to preserve the elements order is relaxed it is much more efficient to replace the element being removed with the last element.

请注意:如果放宽了保留元素顺序的要求,则用最后一个元素替换被删除的元素会更有效率。

回答by MichaelJP

Programming Hubrandomly provided a code snippet which in fact doesreduce the length of an array

Programming Hub随机提供了一个代码片段,它实际上确实减少了数组的长度

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

Not sure if it's behaviour that was added only later. It does the trick though.

不确定它是否是后来才添加的行为。不过它确实有效。

回答by JosephH

If you are most concerned about code size and/or performance (also for WCET analysis, if you need one), I think this is probably going to be one of the more transparent solutions (for finding and removing elements):

如果您最关心代码大小和/或性能(也用于 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;