C++字符串erase函数移除标点失效,LeetCode有效回文题求助
问题原因与解决方案
你的代码存在两个核心问题:
- 迭代器失效导致遍历不完整:使用range-based for循环遍历字符串时,中途调用
erase会破坏迭代器的有效性,循环无法正确遍历修改后的字符串,导致部分标点符号(比如示例中的[和])没被处理。 - 效率低下且逻辑冗余:每次针对单个标点符号调用
remove+erase,需要多次遍历字符串,时间复杂度较高。
正确实现方式
LeetCode的「有效回文」要求仅保留字母和数字字符,忽略大小写,因此可以直接用erase-remove_if惯用法一次性过滤所有非字母数字的字符,再统一转小写,最后判断回文:
#include <algorithm> #include <cctype> bool isPalindrome(string s) { // 移除所有非字母数字的字符 s.erase(remove_if(s.begin(), s.end(), [](char c) { return !isalnum(static_cast<unsigned char>(c)); }), s.end()); // 转换为小写 transform(s.begin(), s.end(), s.begin(), [](char c) { return tolower(static_cast<unsigned char>(c)); }); // 判断回文 int left = 0, right = s.size() - 1; while (left < right) { if (s[left] != s[right]) { return false; } left++; right--; } return true; }
细节说明
isalnum用于判断字符是否为字母或数字,覆盖了题目要求的保留范围,比单独判断标点更准确。- 用
static_cast<unsigned char>转换字符,避免isalnum和tolower处理负数值(比如扩展ASCII字符)时出现未定义行为。 erase-remove_if是C++标准库的高效用法,仅需两次遍历即可完成过滤,时间复杂度为O(n)。
内容的提问来源于stack exchange,提问作者DeZCvr
相关产品推荐
相关产品推荐

