我想删除字符串中的所有元素,但参数a和b指定的字符除外。 看起来很简单,但没有遇到string.erase()的问题。
int is_pattern(string s , char a , char b)
{
int i,l=s.length();
for(i=0;i<l;i++)
{
if(!(s[i]==a || s[i]==b))
{
s.erase(i);
}
}
return l;
}
编译器消息如下:
在抛出'std :: out_of_range'实例后终止调用 what():basic_string :: erase:__ post(是2)&gt; this-&gt; size()(其中 是1)
以上问题属于黑客挑战之一。
答案 0 :(得分:1)
你的&#34;超出范围&#34;错误是因为您正在获取字符串的长度,然后处理每个字符位置。
不幸的是,一旦你开始实际从字符串中删除字符,字符串中的某些字符位置就不再存在,并且在移动到下一次迭代时会跳过一些字符,因为字符在删除时向左移动。
解决这个问题的一种方法是从最右边的字符向下迭代到零,这样删除就不会影响尚待处理的字符位置(受影响的位置在当前位置或右侧,但是你正在移动左)。
另一种方法是使用标准库的功能,特别是remove_if
,例如:
#include <iostream>
#include <algorithm>
#include <string>
bool IsAorB(char ch) {
return (ch == a) || (ch == b);
}
:
str.erase(std::remove_if(str.begin(), str.end(), &IsAorB), str.end());
但是,请记住,这两种这些解决方案可能效率不如更多&#34;手册&#34;处理(见下文)。
对于第二个解决方案,为了使其一般(任何a
或b
),你必须使用一个函数对象,这使得它相当复杂(所以我赢了&#39;详细说明这里。)
所以你可能只想选择手动方法,从旧方法构建一个新字符串,没有违规字符。以下是此方法的一个示例,它为您提供输出0124578998754210
(已移除3
和6
个字符):
#include <iostream>
#include <string>
std::string withoutAorB(const std::string &str, char a, char b) {
std::string newStr;
for (size_t i = 0; i < str.size(); i++)
if ((str[i] != a) && (str[i] != b))
newStr.append(1, str[i]);
return newStr;
}
int main() {
std::cout << withoutAorB("01234567899876543210", '3', '6') << '\n';
}
答案 1 :(得分:0)
您正在删除数组中的字符,因为这些字符不再存在。
解决方案:创建一个新的字符串数组并将所需的值复制到该数组中,并省略不需要的值。