双指针法判断回文最直接高效,时间复杂度O(n)、无需额外空间;需根据需求决定是否忽略大小写及非字母数字字符,避免拷贝或越界错误。

用 std::string 双指针法判断回文最直接
不需要额外空间,时间复杂度 O(n),适合大多数场景。关键点是忽略大小写和非字母数字字符——但如果你的需求就是「严格按字面回文」(比如 "Aa" 不算),那就跳过转换步骤。
常见错误:用 std::reverse 拷贝再比较,浪费内存;或循环时没控制好边界导致越界(比如 i 写成 i 少判中间字符)。
bool isPalindrome(const std::string& s) {
int i = 0, j = s.length() - 1;
while (i < j) {
if (s[i] != s[j]) return false;
++i;
--j;
}
return true;
}处理大小写和符号时用 std::isalnum 和 std::tolower
标准库函数能正确处理 locale,比手写 'a' 更健壮。注意:必须对左右两边都做清洗,否则 "A man a plan a canal Panama" 这类会误判。
- 先跳过非字母数字字符(
!std::isalnum(s[i])) - 再统一转小写比较(
std::tolower(s[i]) != std::tolower(s[j])) - 避免在循环内反复调用
std::tolower两次——可提前存为局部变量
用 std::string_view 提升只读场景性能
如果函数只读不修改字符串(比如校验配置项、日志字段),传 std::string_view 避免隐式构造 std::string 的开销。C++17 起支持,且兼容 C 风格字符串和 std::string。
立即学习“C++免费学习笔记(深入)”;
注意:string_view 不保证以 '\0' 结尾,所以不能传给 expecting C-string 的 API;也不拥有数据,确保原字符串生命周期长于 view。
bool isPalindrome(std::string_view s) {
size_t i = 0, j = s.length();
while (i < --j) {
if (std::tolower(s[i++]) != std::tolower(s[j])) return false;
}
return true;
}遇到中文或 Unicode 字符怎么办
std::string 存的是 UTF-8 字节流,直接按字节比较会出错(比如一个汉字占 3 字节)。此时双指针失效,必须先转成 Unicode 码点序列(如用 ICU 库或 C++20 std::text_encoding),再逐码点比较。
简单项目里更现实的做法是:明确约定输入为 ASCII,或在文档里写死「本函数不支持多字节字符」。强行用 std::wstring + wcin 并不能自动解决 UTF-8 问题,Windows 控制台默认也不是 UTF-8。
真正需要国际化回文检测的场景极少,优先确认需求是否真包含中文——很多所谓“支持中文”的测试用例其实是半角标点混排,靠预处理剔除标点后仍可用字节比较。











