-2

I was solving one simple problem with the use of replace_if but every time it gives me error. Problem:
in a given string remove the adjacent character and make string as compact as possible.
Ex: aabcc will become b and aabbcc will become empty string.

int main()
{
    string s;
    cin>>s;    
    replace_if(s.begin(),s.end(),[](char l, char r){return l == r;},"");
    cout << string(s.begin(),s.end());   
    return 0;
}

Error:

/usr/include/c++/6/bits/stl_algo.h:4280:12: note:   candidate expects 3 arguments, 2 provided  
solution.cc:19:51: note: candidate:  
main()::<lambda(char, char)> 
replace_if(s.begin(),s.end(),[](char l, char r){
W.F.
  • 13,888
  • 2
  • 34
  • 81
InvI
  • 81
  • 2
  • 3
  • 7

1 Answers1

4

std::replace_if operates on a sequence of values of a certain type (in your case, of type char), and can be used to examine each value in the sequence and potentially replace it with another value of the same type. In other words, if allows you to replace all as with bs, but doesn't allow removing elements or basing the predicate on more than the inspected element itself.

What you need is a bit more complicated to compose, but could be done e.g. like this:

auto it = s.begin();
for (;;)
{
  it = std::adjacent_find(it, s.end()); // Find two adjacent same characters
  if (it == s.end()) // If there are none, we're done
    break;
  auto next = std::find_if(it, s.end(), [it](char c) { return c != *it; }); // Find next different character
  it = s.erase(it, next); // Erase all in range [it, next)
}
Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • I think just loop without algos would be simpler, more readable and efficient – Slava May 19 '17 at 17:26
  • @Slava I disagree, since keeping track of adjacent indices/iterators is prone to off-by-one errors. And as far as efficiency goes, I'd assume it to be identical: it's all just one iteration, after all. – Angew is no longer proud of SO May 19 '17 at 17:37