I have to write a fn squeeze(const string &s, char c)
for ex squeeze("haaaaah" , 'a') should give the output hah

string squeeze(const string& s, char c)
{
    string s1 = s;
    string empty ="";
    int count1 = 0;
    string::size_type i = 0;
    for(i = 0; i < s.length(); i++)
    {
        if( (s[i] == c) && (s[i+1] == c)){
        count1 = s.find(c,i);
        s1.replace(count1+1,1,"");
        cout << count1 << endl;
        }
    }
 //s1.replace(i,count1,c);
return s1;
}

this is what i did but not working

One possible solution is processing the string in reverse.
So starting from the end of the string, if string element i == c and element i - 1 == c, then erase element i.

std::string squeeze(const std::string& s, char c)
{
    std::string str = s;
    size_t len = str.length();

    // process the string from end to start
    for (size_t i = len - 1; i > 0; --i)
    {
        if (str[i] == c && str[i - 1] == c)
            str.erase(str.begin() + i);
    }

    return str;
}

std::string s1 = "aaaaaahaaaaaaaaaah";
std::string s2 = squeeze(s1, 'a');

output: ahah

First of all, it is far simpler than it looks.

The first thing I will point out is that if you need a local copy of the string, then you should take that string by value (instead of const-reference), it is preferrable in general to do so, and it also leads to simpler code.

Then, you have to understand that the "squeeze" operation will always reduce the size or leave it intact. In other words, the destination string is always less than or equal to in size as the source string. For these types of algorithms, you can use a standard compacting strategy which involves traversing the array (or string) with two indices (or iterators): one placed at the output position (destination) and one placed at the input position (source).

Finally, to "squeeze" characters, all you really need to do is skip the duplicates.

When understanding these three facts, you get this:

string squeeze(string s, char c)
{
    for(std::size_t i = 0, j = 0; i < s.length(); ++i, ++j) 
    {
        s[j] = s[i];
        while( (i < s.length()) && (s[i] == c) )
            ++i;
    }
    return s.substr(0, j);
}

And that's it!

Edited 3 Years Ago by mike_2000_17: format edits

there is a problem with mike's answer, you just add i too many times, so the result is wrong

Yeah, you're right. Good catch. Here is the correct version:

string squeeze(string s, char c)
{
    for(std::size_t i = 0, j = 0; i < s.length(); ++j) 
    {
        s[j] = s[i];
        do {
            ++i;
        } while( (i < s.length()) && (s[i] == c) );
    }
    return s.substr(0, j);
}
This question has already been answered. Start a new discussion instead.