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个字符的元素
答案 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及更高版本)中,这是很常见的事情,因此值得习惯并使用它。