对 2D 或 3D 向量使用擦除删除习语
Posted
技术标签:
【中文标题】对 2D 或 3D 向量使用擦除删除习语【英文标题】:Using the erase-remove idiom for 2D or 3D vectors 【发布时间】:2015-11-27 05:46:06 【问题描述】:当我尝试将vector.erase()
用于循环内的二维向量时,我遇到了分段错误。代码如下:
vector<vector<int> > fault;
...
...
for(i=0; i<10; i++)
for(j=0; j<fault.size(); j++)
if(pointer[i].val == fault[j][0])
fault.erase(fault.begin() + j); //ERROR HERE!
是不是因为向量故障的大小发生了变化?我可以在这里使用擦除删除成语吗?如果是这样,我会怎么做? 非常感谢!
【问题讨论】:
我在这里看不到任何会导致问题的东西,除非pointer
数组少于 10 个元素。 (请注意,当您从错误中删除元素 j
时,您的下一次循环迭代将跳过向下移动的元素以替换已删除的元素。)
感谢您指出这一点! Pointer
总是有 10 个元素。我尝试调试错误,发现fault.erase() 在vector.h
中输入了某个函数并没有退出。
您必须提供一个最小的示例,就目前而言,您的问题被认为是题外话。请阅读指南,它们还给出了这些规则的理由。也就是说,将您想要保留的那些元素复制到一个新向量(预先保留足够的空间)然后与前一个向量交换会更容易且通常更高效。
【参考方案1】:
代码不会导致您提到的行出现分段错误。
可能是 if 语句导致了分段错误。要么是因为 pointer
不包含 10 个有效元素,要么是因为 fault
在它包含的所有向量中都没有元素 0(零)。
您可以尝试添加此检查:
for(i=0; i<10; i++)
for(j=0; j<fault.size(); j++)
if (fault[j].size() > 0)
if(pointer[i].val == fault[j][0])
fault.erase(fault.begin() + j);
顺便说一句,您的逻辑似乎是错误的,因为您没有测试向量中的所有元素,即当您删除一个元素时,将为下一个元素跳过测试。也许你会需要这个:
for(i=0; i<10; i++)
for(j=0; j<fault.size(); )
if((fault[j].size()>0) && (pointer[i].val == fault[j][0]))
fault.erase(fault.begin() + j);
else
// Only increment when no erase is done
j++;
【讨论】:
非常感谢!我对 C++ 很陌生,这帮助我学到了很多东西。出于好奇,是否可以将擦除删除习语用于多维向量?我在网上查了,但没有找到任何例子。以上是关于对 2D 或 3D 向量使用擦除删除习语的主要内容,如果未能解决你的问题,请参考以下文章
在向量中使用擦除时双重释放或损坏(fasttop)。知道它们的索引,你怎么能擦除向量的几个项目?