【问题标题】:erase() space in string [duplicate]字符串中的擦除()空间[重复]
【发布时间】:2020-12-24 10:17:30
【问题描述】:

这是我为删除给定字符串中的 空格 而编写的代码。它正常工作。

   string a = "hello  there world";
   int n = a.size();
   for(int i =0 ;i<n;++i){
       if(a[i] == ' '){
           a.erase(a.begin()+i);
       }
   }
   cout<<a;

但是对于上面给定的输入(注意在 "hello" 和 "there" 之间有两个 spaces ),我的输出是:

 hello thereworld

hello”和“world”之间仍然有一个空格。

这种行为正常吗?和erase 有关系吗?

【问题讨论】:

  • 删除索引5处的空格后,索引6处原来的空格向左移动,所以在++i之后保持原样。
  • 这是我为删除给定字符串中的空格而编写的代码 -- 你知道你可以简单地完成:a.erase(std::remove(a.begin(), a.end(), ' '), a.end());
  • 不,我没有。谢谢你的一个班轮。那么 remove() 本质上是移除了指定的字符,并返回了一个指向字符串开头的迭代器?
  • std::remove 实际上将字符移动到容器的末尾,并将迭代器返回到被删除字符的开始位置。一般来说,如果您正在编写代码来完成您知道已经完成数千次甚至数百万次的事情,那么通常有一个 STL 算法函数或一组函数可以完成这项工作。从序列中删除某些字符只是其中之一。
  • @PaulMcKenzie std::remove 不会将元素移动到容器的末尾。唯一的数据移动是好的元素向左移动,覆盖“删除”的值。新逻辑结束后的元素具有未指定的值。这不是分区算法。

标签: c++ string std


【解决方案1】:

不,但您的问题是您向前循环并忽略了您循环的字符串在循环时发生变化的事实。

删除一个空格后,字符串的其余部分向后移动一个位置,但您认为当前字符已被检查,即使您只是更改了它。

所以你基本上从不检查紧跟在空格后面的任何字符,因此为什么不删除一行中的第二个空格。

如果您在字符串中循环向后(或在删除空格后手动递减i),它会起作用。

还请注意,出于同样的原因,您事先将a.size() 保存在变量n 中是错误的,因为每次删除空格时它都会更改。您应该在擦除空格后减少n,或者在循环条件中检查i &lt; a.size() 而不是i &lt; n。 (如果你向后循环,那就没问题了。)

所以底线是解决这两个问题的最简单方法是向后循环而不是向前循环:

for (int i = n - 1; i >= 0; i--) 

【讨论】:

    【解决方案2】:

    在删除第一个空格后,您超出了第二个空格,因为您立即增加索引i

    例如,如果您修改循环以便在找到空格的情况下不增加i,而是减少n,它将正常工作,作为您删除的字符之后的下一个字符然后具有相同的索引,并且字符串短一。

    【讨论】:

    • @Alan 哦,没错,已更正!谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-15
    • 1970-01-01
    • 1970-01-01
    • 2020-05-21
    • 2019-09-30
    • 2017-06-12
    相关资源
    最近更新 更多