C++ 如何按索引从 std::vector<> 中删除元素?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/875103/
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:44:01  来源:igfitidea点击:

How do I erase an element from std::vector<> by index?

c++stlvectorerase

提问by dau_man

I have a std::vector<int>, and I want to delete the n'th element. How do I do that?

我有一个 std::vector<int>,我想删除第 n 个元素。我怎么做?

std::vector<int> vec;

vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);

vec.erase(???);

回答by mmmmmmmm

To delete a single element, you could do:

要删除单个元素,您可以执行以下操作:

std::vector<int> vec;

vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);

// Deletes the second element (vec[1])
vec.erase(vec.begin() + 1);

Or, to delete more than one element at once:

或者,一次删除多个元素:

// Deletes the second through third elements (vec[1], vec[2])
vec.erase(vec.begin() + 1, vec.begin() + 3);

回答by CodeBuddy

The erase method on std::vector is overloaded, so it's probably clearer to call

std::vector 上的擦除方法已重载,因此调用可能更清晰

vec.erase(vec.begin() + index);

when you only want to erase a single element.

当您只想擦除单个元素时。

回答by Max

template <typename T>
void remove(std::vector<T>& vec, size_t pos)
{
    std::vector<T>::iterator it = vec.begin();
    std::advance(it, pos);
    vec.erase(it);
}

回答by Eswaran Pandi

The erasemethod will be used in two ways:

erase方法将以两种方式使用:

  1. Erasing single element:

    vector.erase( vector.begin() + 3 ); // Deleting the fourth element
    
  2. Erasing range of elements:

    vector.erase( vector.begin() + 3, vector.begin() + 5 ); // Deleting from fourth element to sixth element
    
  1. 擦除单个元素:

    vector.erase( vector.begin() + 3 ); // Deleting the fourth element
    
  2. 擦除元素范围:

    vector.erase( vector.begin() + 3, vector.begin() + 5 ); // Deleting from fourth element to sixth element
    

回答by Varun Garg

Actually, the erasefunction works for two profiles:

实际上,该erase功能适用于两个配置文件:

  • Removing a single element

    iterator erase (iterator position);
    
  • Removing a range of elements

    iterator erase (iterator first, iterator last);
    
  • 删除单个元素

    iterator erase (iterator position);
    
  • 删除一系列元素

    iterator erase (iterator first, iterator last);
    

Since std::vec.begin() marks the start of container and if we want to delete the ith element in our vector, we can use:

由于 std::vec.begin() 标记了容器的开始,如果我们想删除向量中的第 i 个元素,我们可以使用:

vec.erase(vec.begin() + index);

If you look closely, vec.begin() is just a pointer to the starting position of our vector and adding the value of i to it increments the pointer to i position, so instead we can access the pointer to the ith element by:

如果仔细观察, vec.begin() 只是指向向量起始位置的指针,将 i 的值添加到它会增加指向 i 位置的指针,因此我们可以通过以下方式访问指向第 i 个元素的指针:

&vec[i]

So we can write:

所以我们可以写:

vec.erase(&vec[i]); // To delete the ith element

回答by Clay J

If you have an unordered vector you can take advantage of the fact that it's unordered and use something I saw from Dan Higgins at CPPCON

如果你有一个无序向量,你可以利用它无序的事实,并使用我在 CPPCON 从 Dan Higgins 看到的东西

template< typename TContainer >
static bool EraseFromUnorderedByIndex( TContainer& inContainer, size_t inIndex )
{
    if ( inIndex < inContainer.size() )
    {
        if ( inIndex != inContainer.size() - 1 )
            inContainer[inIndex] = inContainer.back();
        inContainer.pop_back();
        return true;
    }
    return false;
}

Since the list order doesn't matter, just take the last element in the list and copy it over the top of the item you want to remove, then pop and delete the last item.

由于列表顺序无关紧要,只需将列表中的最后一个元素复制到要删除的项目的顶部,然后弹出并删除最后一个项目。

回答by Fabian

If you work with large vectors (size > 100,000) and want to delete lots of elements, I would recommend to do something like this:

如果您使用大向量(大小 > 100,000)并想要删除大量元素,我建议您执行以下操作:

int main(int argc, char** argv) {

    vector <int> vec;
    vector <int> vec2;

    for (int i = 0; i < 20000000; i++){
        vec.push_back(i);}

    for (int i = 0; i < vec.size(); i++)
    {
        if(vec.at(i) %3 != 0)
            vec2.push_back(i);
    }

    vec = vec2;
    cout << vec.size() << endl;
}

The code takes every number in vec that can't be divided by 3 and copies it to vec2. Afterwards it copies vec2 in vec. It is pretty fast. To process 20,000,000 elements this algorithm only takes 0.8 sec!

该代码获取 vec 中不能被 3 整除的每个数字并将其复制到 vec2。然后它在 vec 中复制 vec2。它非常快。要处理 20,000,000 个元素,这个算法只需要 0.8 秒!

I did the same thing with the erase-method, and it takes lots and lots of time:

我用擦除方法做了同样的事情,它需要很多很多时间:

Erase-Version (10k elements)  : 0.04 sec
Erase-Version (100k elements) : 0.6  sec
Erase-Version (1000k elements): 56   sec
Erase-Version (10000k elements): ...still calculating (>30 min)

回答by cammando

To delete an element use the following way:

要删除元素,请使用以下方式:

// declaring and assigning array1 
std:vector<int> array1 {0,2,3,4};

// erasing the value in the array
array1.erase(array1.begin()+n);

For a more broad overviewyou can visit: http://www.cplusplus.com/reference/vector/vector/erase/

有关更广泛的概述,您可以访问:http: //www.cplusplus.com/reference/vector/vector/erase/

回答by explorer

I suggest to read this since I believe that is what are you looking for.https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom

我建议阅读此内容,因为我相信这就是您要寻找的内容。https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom

If you use for example

如果你使用例如

 vec.erase(vec.begin() + 1, vec.begin() + 3);

you will erase n -th element of vector but when you erase second element, all other elements of vector will be shifted and vector sized will be -1. This can be problem if you loop through vector since vector size() is decreasing. If you have problem like this provided link suggested to use existing algorithm in standard C++ library. and "remove" or "remove_if".

您将擦除矢量的第 n 个元素,但是当您擦除第二个元素时,矢量的所有其他元素将被移动,矢量大小将为 -1。如果您遍历向量,这可能会出现问题,因为向量 size() 正在减少。如果您有这样的问题,提供的链接建议使用标准 C++ 库中的现有算法。和“删除”或“remove_if”。

Hope that this helped

希望这有帮助

回答by def

How about this?

这个怎么样?

void squeeze(vector<int> &v)
{
    int j = 0;
    for (int i = 1; i < v.size(); i++)
        if (v[i] != v[j] && ++j != i)
            v[j] = v[i];
    v.resize(j + 1);
}