应选用 std::unordered_map 统计字符频次,遍历时转 unsigned char 防符号扩展;再导出为 vector,按频次降序、ascii 升序排序;输出时区分可打印字符、控制符和非 ascii 字节并格式化。

用 std::map 或 std::unordered_map 统计字符频次
直接遍历字符串,对每个 char 做计数即可。优先选 std::unordered_map<char int></char>,因为字符范围小(最多 256 种),哈希无冲突风险,插入和访问都是 O(1) 平均复杂度;而 std::map 是红黑树,O(log n) 且没必要排序——我们后续要自己重排。
注意点:
-
std::string中的char可能是带符号的,若字符串含非 ASCII 字符(如 UTF-8 中的多字节),char负值会作为 key 导致越界或误统计;此时应先转为unsigned char再映射 - 空字符串、只含空白符的字符串要能正常处理(频次 map 为空)
std::unordered_map<unsigned char int> freq;
for (unsigned char c : s) {
freq[c]++;
}</unsigned>
用 std::vector + std::sort 按频次降序排列
std::unordered_map 本身不支持按 value 排序,必须导出为可排序容器。推荐转成 std::vector<:pair char int>></:pair>,再用自定义 lambda 排序:
- 排序逻辑必须写清楚:先比
second(频次)降序,频次相同时建议按first(字符 ASCII 码)升序,避免相同频次输出顺序不确定 - 别直接对 map 迭代器排序——语法不合法;也别用
std::multimap<int char></int>反向建索引,插入时频次未定,易出错 - 如果原字符串很大但不同字符极少(比如只有 20 种),vector 尺寸很小,排序开销可忽略
std::vector<:pair char int>> vec(freq.begin(), freq.end());
std::sort(vec.begin(), vec.end(), [](const auto& a, const auto& b) {
if (a.second != b.second) return a.second > b.second;
return a.first
<h3>输出时注意字符的可读性与转义</h3>
<p>直接打印 <code>unsigned char</code> 可能输出不可见字符(如 <code>

