如何擦除向量元素中没有特定字符的元素

how to erase an element hasn't a certain character in vector elements

我找到了很多关于擦除具有特定字符的向量元素的答案 但我尝试制作其中一些解决方案来擦除没有该字符但不起作用的元素

 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个字符的元素

你可以这样做:

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 将所有 not 匹配条件的元素移到前面,替换满足条件的元素。当作为第三个参数给出的 lambda returns 为真时,此处的条件得到满足。 newEnd是指向未移除元素之后的第一个元素的迭代器。

例如,如果输入是这样的:{"aaa", "bbx", "ccc"},在调用 remove_if 之后向量看起来像这样:{"aaa", "ccc", <used to be bbx>}.

第二行删除从newEnd开始的所有元素。所以在上面的例子中,你最终得到 {"aaa", "ccc"}.

这里的条件是一个 lambda,对于每个既不包含 'x' 也不包含 'X'.

的元素 returns 为真

这与您尝试过的情况相同 - 并且是正确的。与您的原始代码不同的问题。

查看: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 和更新版本)中很常见,因此值得习惯并使用它。