Preeti Patel
Preeti Patel

Reputation: 11

how to delete elements from string in c++

I want to delete all the elements in a string except the character specified by arguments a and b. It seems quite simple but not getting the problem of 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;
}

the compiler message is following:

terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::erase: __pos (which is 2) > this->size() (which is 1)

above problem belongs to one of the hackerrank challenge.

Upvotes: 1

Views: 1572

Answers (2)

paxdiablo
paxdiablo

Reputation: 881283

Your "out of range" error is because you are getting the length of the string up front, then processing every one of those character positions.

Unfortunately, once you start actually removing characters from the string, some of those character positions no longer exist in the string and you skip some characters when moving to the next iteration, because the characters are shifted left on removal.


One way to fix this would be to iterate from the rightmost character down to zero so that deletion will not affect character positions yet to be processed (affected positions are at current position or to the right, but you're moving left).


Another way would be to use the facilities of the standard library, specifically remove_if, something like:

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

However, keep in mind that both those solutions may not be as efficient as more "manual" processing (see below).

And for the second solution, in order to make it general (any a or b), you have to use a function object, which makes it rather complex (so I won't detail it here).


So you may want to just opt for the manual method, constructing a new string from the old one, sans the offending characters. Here's an example of this method, which gives you the output 0124578998754210 (3 and 6 characters removed):

#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';
}

Upvotes: 1

stillLearning
stillLearning

Reputation: 170

You are removing the characters from the array because of which the positions donot exist anymore.

Solution: Create a new string array and copy the needed values to it and omit the ones not needed.

Upvotes: 0

Related Questions