【问题标题】:Why do I need to cast the argument of algorithm remove()?为什么我需要强制转换算法 remove() 的参数?
【发布时间】:2017-06-15 18:58:44
【问题描述】:

我正在尝试从"helloworld" 等字符串中删除连续的重复字符,并删除所有出现的重复字符。在这种情况下,它是'l',所以新字符串应该是"heoword"。我写了这样的代码:

#include <algorithm> 
#include <string>
#include <iostream>  

using namespace std; 

int main() { 
  string s = "helloworld"; 
  for (int i = 0; i < s.length() - 1; i++) { 
    if (s[i] == s[i+1]) { 
      s.erase(remove(s.begin(), s.end(), s[i]), s.end()); // PROBLEM
      cout << s << endl; // printing `heowrld`, instead of `heoword`
    } 
  }
  return 0;  
}

除非我像(char)s[i] 一样投射s[i],否则上面的代码不起作用。我为字符串查找了运算符[],它返回了对位置字符的引用。 remove 方法还接受 const T&amp; val 作为要替换字符的参数。既然它们都是同一类型,为什么我不能把s[i] 作为remove 方法的参数?

附言这不是作业问题。通过在remove 中转换s[i],我可以获得正确的输出,但我想知道为什么我需要转换s[i]

【问题讨论】:

标签: c++ pointers casting reference


【解决方案1】:

这里的问题是您将值从您自己的下方移除。来看看

#include <iostream>

int main() 
{
    int a = 5, b = 10;
    int & ref = a;
    std::cout << "a: " << a << " b: " << b << " ref: " << ref << "\n";
    std::swap(a, b);
    std::cout << "a: " << a << " b: " << b << " ref: " << ref << "\n";
}

如果你运行它,你会得到

a: 5 b: 10 ref: 5
a: 10 b: 5 ref: 10

如您所见,ref 并没有移动到现在关注b,而是保持a(应该如此)并打印a 的新值。

我们看到了同样的事情

s.erase(remove(s.begin(), s.end(), s[i]), s.end());

由于s[i] 是对字符串中元素的引用,因此它的值会随着 remove 交换元素而改变。所以它删除了两个l,然后它还删除了最后一个o,因为o被移动到l曾经占据的相同位置,但它只有在它通过第一个o之后才会这样做字符串。

强制转换“修复”的原因是因为现在您不再引用字符串的元素。您创建一个临时变量并使用该变量值删除l's。

【讨论】:

    猜你喜欢
    • 2014-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-05
    • 1970-01-01
    • 1970-01-01
    • 2014-03-16
    • 2021-05-08
    相关资源
    最近更新 更多