简体   繁体   English

删除 C++ 中字符串中的所有相邻重复项:为什么我的迭代器没有再次进入 for 循环

[英]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/ 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.在这个 Leetcode 问题中,我尝试在不使用堆栈的概念的情况下做到这一点。 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 * .您的循环边界i < s.length()是错误的,因为它会让s[i + 1]越界访问字符串*
  • 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.当找到匹配项时,您需要重置i ,您可以这样做,但是i++直接紧随其后,因此它永远不会在s[0] == s[1]处再次找到匹配项。

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. *越界访问将真正访问终止\0 (自 C++11 起,之前未定义的行为),但这是不必要的,因为无论如何您都无法erase它。


A somewhat quicker version would be to not reset i to 0 , but to continue searching at the current position:一个更快的版本是不将i重置为0 ,而是继续搜索当前的 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循环的主要问题

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.是在擦除两个相邻元素后,变量i在 if 语句中设置为0 ,然后在 for 语句中立即递增。 So in the next iteration of the loop the variable i is equal to 1 .所以在循环的下一次迭代中,变量i等于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' .擦除"bb"后,字符串变为等于"aa" ,但之后变量i等于1 ,在循环的下一次迭代中,您将比较s[1]s[2] ,它们是'a''\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' .请注意,根据 C++ 标准s[s.length()]等于'\0' So you may use the comparison s[i] == s[i+1] .所以你可以使用比较s[i] == s[i+1] According to the assignment in the provided link the string contains only low case letters.根据提供的链接中的分配,该字符串仅包含小写字母。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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