Vti*_*tik -1 c++ vector erase erase-remove-idiom
比如,我在代码中有两个向量,我希望使用迭代器擦除向量"data"中的向量"index_to_filter"索引的元素.代码中的虚拟方式只是指出明显的错误.到目前为止,我无法让它工作,也不知道这是否可以成为擦除 - 删除 - 成语?.有没有办法去错过它?
谢谢.
#include <iostream>
#include <vector>
int main()
{
std::vector<int> data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int> index_to_filter{ 1, 5, 8 };
/* needed result data = { 0, 2, 3, 4, 6, 7, 9 }*/
std::vector<int>::iterator iter = index_to_filter.begin();
while (iter != index_to_filter.end())
{
std::vector<int>::iterator iter_data = data.begin() + *iter;
iter_data = data.erase(iter_data);
iter++;
}
/* Throws : vector erase iterator outside range */
for (int i: data)
std::cout << i << std::endl;
system("pause");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
PS:vector.erase问题在这里被滥用了几十次,但没有找到这个问题的线索!
PS:不欢迎使用没有迭代器的解决方案.(没有冒犯的意思 !)
谢谢
你的问题很简单:
std::vector<int> index_to_filter{ 1, 5, 8 };
Run Code Online (Sandbox Code Playgroud)
您的目的是从另一个数组中删除元素#1,#5和#8,然后从元素#1开始:
Value 0 1 2 3 4 5 6 7 8 9
Index 0 1 2 3 4 5 6 7 8 9
^ ^ ^
Run Code Online (Sandbox Code Playgroud)
底线是"索引"行,是向量的索引.顶行"值"行是向量中该位置的值.当你开始时,这两个值是相同的.
插入符号标记要删除的索引,并从元素#1开始.
你忽略的基本差距是,当你从矢量中移除一个元素时,你并没有一个间隙的黑洞,那个位置的空洞.容器中的所有后续值都会转移.因此,当您删除元素#1时,剩余的值会移位:
Value 0 2 3 4 5 6 7 8 9
Index 0 1 2 3 4 5 6 7 8
^ ^
Run Code Online (Sandbox Code Playgroud)
您要删除的下一个元素是元素#5.不幸的是,向量中该位置的值不再是5.它是6,因为数组已经移位.您的代码比继续执行并删除索引位置#5,其结果如下:
Value 0 2 3 4 5 7 8 9
Index 0 1 2 3 4 5 6 7
^
Run Code Online (Sandbox Code Playgroud)
你已经离开这里了.但现在,您的代码尝试删除不再存在的索引#8,因为该向量现在更短.一旦你的代码试图这样做,你就会爆炸.
因此,总而言之:您遗漏的是一个简单的事实,即从向量的中间移除一个值会将所有后续值向上移动一个位置,以填充已删除元素留下的间隙,以及您编写的代码没有考虑到这一点.
最简单的解决方案是将元素从最高索引位置移除到最低位置.在您的代码中,您已经index_to_filter按排序顺序,因此不是从开头index_to_filter到结尾迭代,而是从最低索引到最高索引,从最后一个索引index_to_filter到第一个索引向后迭代,因此您的代码尝试删除索引8,5,然后1,这样每次删除元素都不会影响较低的索引位置.
| 归档时间: |
|
| 查看次数: |
339 次 |
| 最近记录: |