矢量用迭代器擦除特定索引(不基于范围或条件)
vector erase specific indexes with iterators (not based on range or condition)
说,我在代码中有两个向量,如下所示,我想擦除向量 "index_to_filter" 中由向量 "index_to_filter" 索引的元素 "data" 使用迭代器.代码中的虚拟方式只是指出明显的错误。到目前为止,我无法让它工作,也无法弄清楚这是否可能是 erase-remove-idiom?。有没有办法,我想念它?
谢谢。
#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;
}
PS: vector.erase 问题在这里被省略了几十次,但没有找到这个问题的线索!
PS:不欢迎没有 迭代器 的解决方案。 (无意冒犯!)
谢谢
如果 index_to_filter
保证排序,您应该能够以相反的顺序删除元素 - 只要没有删除以前的条目,要过滤的索引仍然是正确的。
因此只需在您当前的代码中调用 index_to_filter.rbegin()
和 index_to_filter.rend()
。
你的问题很简单:
std::vector<int> index_to_filter{ 1, 5, 8 };
您打算从另一个数组中删除元素 #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
^ ^ ^
最后一行,即 "index" 行,是向量的索引。顶行 "value" 行是向量中该位置的值。当你启动时,这两个值是相同的。
插入符号标记您要删除的索引,您从元素 #1 开始。
您忽略的根本差距是,当您从向量中删除一个元素时,您并没有完全打开一个黑洞,那个位置是一个空洞。容器中的所有后续值都会转移。因此,当您删除元素 #1 时,剩余的值会转移:
Value 0 2 3 4 5 6 7 8 9
Index 0 1 2 3 4 5 6 7 8
^ ^
您要删除的下一个元素是元素 #5。不幸的是,向量中那个位置的值不再是 5。而是 6,因为数组已经移位。您的代码然后继续并删除索引位置 #5,结果如下:
Value 0 2 3 4 5 7 8 9
Index 0 1 2 3 4 5 6 7
^
您已经离开这里 rails。但是现在,您的代码试图删除不再存在的索引 #8,因为向量现在更短了。一旦您的代码尝试这样做,您就会崩溃。
因此,总而言之:您缺少的是一个简单的事实,即从向量中间删除一个值会将所有后续值向上移动一个位置,以填补删除元素留下的空白,而您编写的代码未能说明这一点。
最简单的解决方案是从最高索引位置到最低索引位置删除元素。在您的代码中,您已经按排序顺序排列了 index_to_filter
,因此不是从 index_to_filter
的开头迭代到它的结尾,从最低索引到最高索引,而是从 index_to_filter
中的最后一个索引向后迭代=14=] 到第一个,所以你的代码尝试删除索引 8、5,然后是 1,这样每次删除元素都不会影响较低的索引位置。
说,我在代码中有两个向量,如下所示,我想擦除向量 "index_to_filter" 中由向量 "index_to_filter" 索引的元素 "data" 使用迭代器.代码中的虚拟方式只是指出明显的错误。到目前为止,我无法让它工作,也无法弄清楚这是否可能是 erase-remove-idiom?。有没有办法,我想念它?
谢谢。
#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;
}
PS: vector.erase 问题在这里被省略了几十次,但没有找到这个问题的线索!
PS:不欢迎没有 迭代器 的解决方案。 (无意冒犯!)
谢谢
如果 index_to_filter
保证排序,您应该能够以相反的顺序删除元素 - 只要没有删除以前的条目,要过滤的索引仍然是正确的。
因此只需在您当前的代码中调用 index_to_filter.rbegin()
和 index_to_filter.rend()
。
你的问题很简单:
std::vector<int> index_to_filter{ 1, 5, 8 };
您打算从另一个数组中删除元素 #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
^ ^ ^
最后一行,即 "index" 行,是向量的索引。顶行 "value" 行是向量中该位置的值。当你启动时,这两个值是相同的。
插入符号标记您要删除的索引,您从元素 #1 开始。
您忽略的根本差距是,当您从向量中删除一个元素时,您并没有完全打开一个黑洞,那个位置是一个空洞。容器中的所有后续值都会转移。因此,当您删除元素 #1 时,剩余的值会转移:
Value 0 2 3 4 5 6 7 8 9
Index 0 1 2 3 4 5 6 7 8
^ ^
您要删除的下一个元素是元素 #5。不幸的是,向量中那个位置的值不再是 5。而是 6,因为数组已经移位。您的代码然后继续并删除索引位置 #5,结果如下:
Value 0 2 3 4 5 7 8 9
Index 0 1 2 3 4 5 6 7
^
您已经离开这里 rails。但是现在,您的代码试图删除不再存在的索引 #8,因为向量现在更短了。一旦您的代码尝试这样做,您就会崩溃。
因此,总而言之:您缺少的是一个简单的事实,即从向量中间删除一个值会将所有后续值向上移动一个位置,以填补删除元素留下的空白,而您编写的代码未能说明这一点。
最简单的解决方案是从最高索引位置到最低索引位置删除元素。在您的代码中,您已经按排序顺序排列了 index_to_filter
,因此不是从 index_to_filter
的开头迭代到它的结尾,从最低索引到最高索引,而是从 index_to_filter
中的最后一个索引向后迭代=14=] 到第一个,所以你的代码尝试删除索引 8、5,然后是 1,这样每次删除元素都不会影响较低的索引位置。