简体   繁体   中英

Remove All Adjacent Duplicates In String in C++: Why is my iterator not entering into the for loop again

https://leetcode.com/problems/remove-all-adjacent-duplicates-in-string/

In this Leetcode question, I tried to do it without using the concept of a stack. But according to the answer, I get the loop is not getting completed, why is that the case here?

class Solution {
    public:
    string removeDuplicates(string s) {
        
        for (int i = 0; i<s.length(); i++) {
            if(s[i] == s[i+1]){
                s.erase(i,2);
                i=0;
            }
            
        }
        
        return s;
    }
};

This is the error I am getting:

图片

  • Your loop boundary, i < s.length() , is wrong since it'll let s[i + 1] access the string out of bounds * .
  • You need to reset i when a match is found, which you do, but it's followed by i++ directly, so it will never find a match at s[0] == s[1] again.

Fixed:

string removeDuplicates(string s) {
    for (unsigned i = 0; i + 1 < s.length();) { // corrected loop bounds
        if (s[i] == s[i + 1]) {
            s.erase(i, 2);
            i = 0;
        } else ++i;                            // only add 1 if no match is found
    }
    return s;
}

* The out of bounds access will really access the terminating \0 (since C++11, undefined behavior before that), but it's unnecessary since you can't erase it anyway.


A somewhat quicker version would be to not reset i to 0 , but to continue searching at the current position:

string removeDuplicates(string s) {
    for (size_t i = s.length(); i-- > 1;) {
        if (s[i-1] == s[i]) {
            s.erase(i-1, 2);
            ++i;
        }
    }
    return s;
}

The main problem of this for loop

for (int i = 0; i<s.length(); i++) {
    if(s[i] == s[i+1]){
        s.erase(i,2);
        i=0;
    }
    
}

is that after erasing two adjacent elements the variable i is set to 0 within the if statement and then at once is incremented in the for statement. So in the next iteration of the loop the variable i is equal to 1 .

Consider the following string

"abba'

after erasing "bb" the string becomes equal to "aa" but after that the variable i is equal to 1 and in the next iteration of the loop you are comparing s[1] and s[2] that are 'a' and '\0' .

Rewrite the loop at least the following way

for ( std::string::size_type i = 0; i < s.length(); ) 
{
    if ( s[i] == s[i+1] )
    {
        s.erase(i,2);
        i=0;
    }
    else
    {
        ++i;
    }
}

Pay attention to that according to the C++ Standard s[s.length()] is equal to '\0' . So you may use the comparison s[i] == s[i+1] . According to the assignment in the provided link the string contains only low case letters.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM