C++实现无重复字符最长子串时报C2677==运算符错误如何修复
报错原因
这个C2677编译错误本质是类型不匹配:
- 你定义的
substr是std::string类型的数组,每个元素都是一个完整的字符串对象 - 比较符左侧的
str[i+1]是从输入串里取的单个char类型字符
标准库没有提供char和std::string直接用==比较的运算符重载,编译器找不到合法的转换规则,自然会报错。
另外你原代码就算改了类型问题也跑不对,还有两个硬伤:
- 循环越界:当
i遍历到字符串最后一个字符(下标str.size()-1)时,你还在访问str[i+1],会读到字符串末尾的非法内存,触发未定义行为 - 去重逻辑错误:碰到重复字符就直接把计数、子串索引全清0,会丢掉重复字符后面的有效子串。比如输入
abca,碰到最后一个a和开头a重复就清零,会直接漏掉长度为3的bca子串,计算结果完全错误。
修复方案
- 别用
string数组存单个字符,要么换成char数组,要么更省事直接开个长度128的布尔数组标记字符是否出现过——ASCII字符总共就128个,判断重复不用循环遍历,效率高很多。 - 调整循环边界,不要访问超出字符串长度的内存。
- 用滑动窗口的思路维护无重复子串的左右边界:碰到重复字符时,把左边界移到重复字符的下一位即可,不用把整个窗口清空。
修复后可直接运行的代码:
#include <iostream> #include <string> #include <cstring> #include <algorithm> using namespace std; int main() { string str; getline(cin, str); bool charExist[128]; memset(charExist, 0, sizeof(charExist)); int maxLen = 0; int left = 0; for (int right = 0; right < str.size(); right++) { char cur = str[right]; // 当前字符已在窗口内,移动左边界直到把重复字符移出窗口 while (charExist[cur]) { charExist[str[left]] = false; left++; } charExist[cur] = true; maxLen = max(maxLen, right - left + 1); } cout << maxLen << endl; return 0; }
输入测试用例abcacbcc时,程序会正确输出结果3。
内容的提问来源于stack exchange,提问作者NatruSs
相关产品推荐
相关产品推荐

