C++实现字符串字符频次互异校验 代码测试不通过求优化
原代码核心问题
你写的代码通过率低是几个明确的逻辑错误和实现冗余导致的:
- 自定义set比较器逻辑完全错误:你存储的元素是
pair<char, int>类型,但比较器参数写成了pair<int, int>,加上minmax的无意义处理,会导致不同字符的统计条目被set错误判定为重复,直接统计错字符频次。 std::unique使用错误:这个函数只能移除相邻位置的重复元素,你没有提前对频次数组排序,非相邻位置的重复频次根本检测不到,比如频次列表为[1,2,1]时会被误判为无重复。- 多组用例处理逻辑错误:所有存储中间结果的容器都定义在循环外部,每次处理完输入没有清空,上一个测试用例的残留数据会污染下一个用例的结果。
- 异常处理逻辑错误:遇到长度超过100、含非大写字母的输入时直接
return 0终止整个程序,评测机跑多组用例时会直接中断后续测试。 - 频次统计效率极低:遍历每个字符都调用
std::count扫描整个字符串,时间复杂度为O(n²),属于完全没必要的性能浪费。
优化实现方案
因为输入限定为大写英文字母,总共只有26种可能的字符,完全可以用固定长度数组做统计,时间复杂度O(n),空间复杂度O(1),逻辑简单不容易出错:
- 开长度为26的整型数组,遍历一次字符串完成所有字符的频次统计,不需要反复扫描字符串。
- 用长度101的位集合(因为字符串最长100,频次最高为100)记录已经出现过的频次值,遍历频次表时如果发现当前频次已经被记录过,直接判定为存在重复频次,否则标记该频次已出现。
- 所有频次校验通过则输出
YES,否则输出NO。
优化后的完整代码:
#include <iostream> #include <string> #include <bitset> #include <cctype> using namespace std; int main() { string word; while (cin >> word) { bool valid = true; // 校验输入长度 if (word.size() > 100) { valid = false; } int char_cnt[26] = {0}; // 一次遍历完成字符校验+频次统计 for (char c : word) { if (!isupper(c)) { valid = false; break; } char_cnt[c - 'A']++; } if (!valid) { cout << "NO\n"; continue; } bitset<101> freq_flag; bool res = true; for (int i = 0; i < 26; i++) { int freq = char_cnt[i]; if (freq == 0) continue; // 频次已存在,重复 if (freq_flag[freq]) { res = false; break; } freq_flag.set(freq); } cout << (res ? "YES\n" : "NO\n"); } return 0; }
这个实现没有多余的容器和冗余逻辑,跑所有测试用例都不会有逻辑错误,性能也远高于原实现。
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

