如何在c ++中删除字符串中的元素

时间:2017-01-25 06:34:44

标签: c++11

我想删除字符串中的所有元素,但参数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)

以上问题属于黑客挑战之一。

2 个答案:

答案 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;处理(见下文)。

对于第二个解决方案,为了使其一般(任何ab),你必须使用一个函数对象,这使得它相当复杂(所以我赢了&#39;详细说明这里。)

所以你可能只想选择手动方法,从旧方法构建一个新字符串,没有违规字符。以下是此方法的一个示例,它为您提供输出0124578998754210(已移除36个字符):

#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)

您正在删除数组中的字符,因为这些字符不再存在。

解决方案:创建一个新的字符串数组并将所需的值复制到该数组中,并省略不需要的值。