C++学习记录-旧题新做-回文排列
·
C++解法(自己写的):
class Solution {
public:
bool canPermutePalindrome(string s) {
int max = s[0];
int min = s[0];
for(int i = 0; s[i] != '\0'; i++) {
// 找到字符串中ASCII码最大的和最小的,用于后续创建哈希表
if(max <= s[i]) {
max = s[i];
}
if(min >= s[i]) {
min = s[i];
}
}
std::vector<int> arr(max - min + 1, 0);
// 统计每种字符出现的次数
for(int i = 0; s[i] != '\0'; i++) {
arr[s[i] - min]++;
}
int odd = 0;
for(int i = 0; i < max-min+1; i++) {
// 统计出现奇数次的字符数量
if(arr[i]%2 != 0) {
odd++;
}
}
if(odd <= 1) {
return true;
}
else {
return false;
}
}
};
下面是AI辅助修改为更C++风格的代码:
class Solution {
public:
bool canPermutePalindrome(const std::string& s) {
if (s.empty()) return true;
char max_c = s[0];
char min_c = s[0];
for (char c : s) {
if (c > max_c) max_c = c;
if (c < min_c) min_c = c;
}
std::vector<int> arr(max_c - min_c + 1, 0);
for (char c : s) {
arr[c - min_c]++;
}
int odd = 0;
for (int count : arr) {
if (count % 2 != 0) ++odd;
}
return odd <= 1;
}
};
在C++中,用std::vector<int> arr(n, 0);可以等价于C中的calloc(n, sizeof(int));
刚开始的代码主要有这些地方不符合C++风格:
❌ 问题 1:使用 s[i] != '\0' 遍历字符串(C 风格)
这是典型的 C 字符串写法,但:
std::string 并不是以 '\0' 作为遍历终止条件的容器!
这在 C++ 风格中是不推荐的。
正确 C++ 用法应该用:
-
s.size() -
Range-based for
-
迭代器
即可。
❌ 问题 2:max、min 用 int,并且命名和 std::max/min 冲突
max min 是标准库函数名,容易冲突。
而且你用 int 存字符,也是 C 风格。
建议用:
char max_c = s[0];
char min_c = s[0];
char max_c = s[0]; char min_c = s[0];
如果需要计算差值,再强制转成 unsigned char 或 int。
❌ 问题 3:for 循环下标也用 int,不符合 C++ 容器约定
std::string.size() 返回 size_t,用 int 容易出现类型警告。
❌ 问题 4:s[i] 连续访问多次,不现代
C++ 更推荐:
for (char c : s)
for (char c : s)
❌ 问题 5:可以避免第一次遍历找 min/max
因为 ASCII 字符最多 128 种,也可以直接定义固定大小:
std::array<int, 128> count{};
std::array<int, 128> count{};
但如果你坚持按原思路写,也可以。
更多推荐


所有评论(0)