从矢量擦除元素

时间:2012-02-26 10:01:33

标签: c++ vector elements erase

我将以下向量传递给函数

void WuManber::Initialize( const vector<const char *> &patterns, 
                      bool bCaseSensitive, bool bIncludeSpecialCharacters, bool bIncludeExtendedAscii )

我想删除长度小于2的任何元素 我尝试了以下但它甚至没有编译 你能告诉我这里缺少的东西吗?

for(vector<const char *>::iterator iter = patterns.begin();iter != patterns.end();iter++)
 {//my for start
 size_t lenPattern = strlen((iter).c_str);
 if ( 2 > lenPattern )
 patterns.erase(iter);
 }//my for end

3 个答案:

答案 0 :(得分:2)

除了其他人指出的问题之外,在迭代它时从矢量中删除项目是个坏主意。有些技术可以做到,但它通常是缓慢而脆弱的。对于来自向量的大量随机擦除,remove_if几乎总是更好的选择:

#include <algorithm>
bool less_than_two_characters(const char* str) { return strlen(str) < 2; }

void Initialize(vector<const char*>& v) {
    v.erase(std::remove_if(v.begin(), v.end(), less_than_two_characters), v.end());
}

在C ++ 0x中,您可以使用lambda函数更简洁地执行此操作,但上述更可能适用于稍微较旧的编译器。

答案 1 :(得分:1)

这不起作用,因为如果从向量中删除某些内容,则会使迭代器失效。

它可能无法编译,因为您以错误的方式使用迭代器。您可以尝试iter-&gt; c_str或(* iter).c_str。另一方面,给我们错误信息;)

接下来,您尝试修改const向量。这就是编译器抱怨的原因。

您可以使用索引执行此操作,如下所示:

for (int i = 0; i < patterns.size(); ++i) {
    size_t lenPattern = strlen(patterns[i]);
    if (2 > lenPattern) {
      patterns.erase(patterns.begin() + i);
      --i;
    }
}

然而,这并不是很优雅,因为我操纵了反击......

答案 2 :(得分:0)

首先,正如Tim所提到的,patterns参数是一个const引用,因此编译器不会让你修改它 - 如果你想要删除它中的元素,请更改它。

请注意,iter'指向'指针(char const*是特定的)。所以你取消引用迭代器来获取字符串指针:

size_t lenPattern = strlen(*iter);
if ( 2 > lenPattern )
iter = patterns.erase(iter);

此外,在代码段的最后一行中,iter被分配了erase()返回的任何内容,以使其成为有效的迭代器。

请注意,擦除iter指向的元素不会释放向量中指针指向的任何字符串。目前尚不清楚是否有必要,因为向量可能不会“拥有”指向的字符串。