stl中字符串中的擦除关键字的工作?
Posted
技术标签:
【中文标题】stl中字符串中的擦除关键字的工作?【英文标题】:Working of erase keyword in string in stl? 【发布时间】:2018-08-17 15:41:42 【问题描述】:我编写了这段代码来从字符串中删除辅音,但我的答案不正确。那么我应该在这段代码中进行哪些更改以使其正常工作。此外,当我从无序集中删除空格字符(即最后一个元素)时,输出对我来说是意料之外的。所以请帮助我理解这段代码发生了什么?
#include<bits/stdc++.h>
using namespace std;
int main()
unordered_set<char> a='a','e','i','o','O','u','U','A','E','I',' ';
string s="what are you doing";
string ::iterator it;
for(it=s.begin();it!=s.end();it++)
if(a.find(*it)==a.end())
s.erase(it);
cout<<s;
return 0;
【问题讨论】:
您在循环时更改了字符串,这不起作用,因为您使迭代器无效。 @πάνταῥεῖ 实际上std::string::erase
doc 并没有说它使迭代器无效en.cppreference.com/w/cpp/string/basic_string/erase hmm
建议:谨慎使用#include<bits/stdc++.h>
(explanation) 和using namespace std;
(explanation)。使用两者时要更加小心,因为它们会放大彼此的一些最坏影响。
为什么要否决并关闭请求? OP 创建了minimal reproducible example 并提供了足够的信息恕我直言。
【参考方案1】:
您的代码有问题,当您删除符号时
s.erase(it);
然后通过循环增加它,你跳过一个符号,也可能越过字符串的末尾。修复代码的可能解决方案:
for(it=s.begin();it!=s.end();)
if(a.find(*it)==a.end())
it = s.erase(it);
else
++it;
注意1:通常在 STL 容器中,当迭代器擦除元素时,该迭代器无效。尽管std::string::erase()
的文档并没有说任何迭代器都无效,但这里可能不是这种情况。无论如何,我提供的代码在任何情况下都适用于任何容器,也可以解决您的问题。
但最好使用erase-remove 成语使用std::remove_if()
:
s.erase( std::remove_if( s.begin(), s.end(), [a] ( char c ) return a.count(c) == 0; ), s.end() );
注意2:包含“bits/stdc++.h”不是一个好主意
live example
【讨论】:
一定是cppreference失败,例如end()
迭代器肯定失效了....
@user463035818 对,尚不清楚it
是否失效。看起来值得在 SO 中提出另一个问题。
remove/erase-idiom 具有线性的最坏情况复杂性。对于另一种方法,它是二次的。因此,使用它是不明智的,关于迭代器是否失效的讨论有点没有实际意义。请注意,字符串的结尾发生了变化。由于字符串是连续的,因此前一个迭代器的副本超出了范围的末尾,显然是无效的。以上是关于stl中字符串中的擦除关键字的工作?的主要内容,如果未能解决你的问题,请参考以下文章