如何删除元素在矢量元素中没有特定字符

时间:2018-06-20 20:49:11

标签: c++ vector erase

我发现许多消除向量元素具有特定字符的答案 但我尝试提出一些解决方案,以消除没有该特征但不起作用的元素

 for(int k=0; k<temp.size();k++)
{
     while(temp[k].find_first_of("xX")!= string::npos)
     {
         temp.erase(temp.begin()+k);
     }
}
variables_print.push_back(temp);

在一个示例中,这些代码擦除了具有char“ xX”的元素,但我尝试将其设置为 temp [K] .find_first_not_of(“ xX”),但无效

也将其设置为 temp [K] .find_first_of(“ xX”)== string :: npos 无效

如何删除没有x或X个字符的元素

1 个答案:

答案 0 :(得分:1)

您可以这样操作:

auto newEnd = std::remove_if(v.begin(), v.end(),
    [](const auto& s) { return s.find_first_of("xX") == std::string::npos; });
v.erase(newEnd, v.end());

remove_if将所有不符合条件的元素移到最前面,替换满足条件的元素。当作为第三个参数给出的lambda返回true时,这里的条件得到满足。 newEnd是指向未删除元素之后的第一个元素的迭代器。

例如,如果输入是{"aaa", "bbx", "ccc"},则在调用remove_if之后,向量将如下所示:{"aaa", "ccc", <used to be bbx>}

第二行删除所有从newEnd开始的元素。因此,在上面的示例中,您最终得到了{"aaa", "ccc"}

这里的条件是一个lambda,它对不包含'x''X'的每个元素都返回true。

这是您尝试过的相同条件-正确。您的原始代码有问题。

查看:while(temp[k].find_first_of("xX")!= string::npos)。如果字符串不包含X,则此嵌套循环的主体将不会执行,并且不会删除任何内容。另外,您可以使用简单的if语句替换循环。

外循环还有另一个问题。即使您刚刚删除了一个元素,您也会每次增加k。请考虑以下示例:{"x", "x"}。每次递增k时,您将跳过第二个字符串并以{"x"}结尾。

更正后的代码看起来像这样:

for(size_t k=0; k<v.size(); )
{
     if(v[k].find_first_of("xX") == std::string::npos)
     {
         v.erase(v.begin()+k);
     }
     else
     {
          ++k;
     }
}

将此与第一个版本进行比较。它不仅更短,而且还留出了更少的bug空间。

正如@Bob_在评论中指出的那样,第一个版本称为erase-remove idiom。在现代C ++(即C ++ 11及更高版本)中,这是很常见的事情,因此值得习惯并使用它。