编写一个算法frequency,统计在一个输入字符串中各个不同字符出现的频度。用适当的测试数据来验证这个算法
碰到这个题目我的思路是采用键值对的方式实现,出现的新的字符就作为键,出现的次数为值,最终形成一个键值对列表,比如按ASCII编码统计,仅记录0-9 ,a-z的出现频率。下面是我查出的一些实现方法
1.数组索引法
限定ASCII编码,创建一个数组,int counts[36],‘0-9’和‘a-z’一共36个,分别对应索引,他们的值counts[索引值]就是出现次数
#include <iostream>
#include <string>
using namespace std;void frequency(const string& str) {int counts[36] = {0}; // 索引0-9: 数字,10-35: A-Zfor (char c : str) {if (c >= '0' && c <= '9') {counts[c - '0']++;} else if (c >= 'A' && c <= 'Z') {counts[c - 'A' + 10]++;}// 忽略非法字符}// 输出结果for (int i = 0; i < 36; i++) {if (counts[i] > 0) {char ch = (i < 10) ? '0' + i : 'A' + i - 10;cout << ch << ": " << counts[i] << endl;}}
}// 测试
int main() {frequency("AAABBB123"); // 输出:A:3, B:3, 1:1, 2:1, 3:1return 0;
}
2.std::map容器实现
map就是一个有序的键值对,键是字符,值是出现频率
#include <iostream>
#include <map>
#include <string>
using namespace std;void frequency(const string& str) {map<char, int> freq;for (char c : str) {if (('0' <= c && c <= '9') || ('A' <= c && c <= 'Z')) {freq[c]++;}}for (const auto& pair : freq) {cout << pair.first << ": " << pair.second << endl;}
}// 测试
int main() {frequency("HELLO123"); // 输出:1:1, 2:1, 3:1, E:1, H:1, L:2, O:1return 0;
}
3.std::unorder_map无序键值对
原理和map一样,只不过输出没有排序
#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;void frequency(const string& str) {unordered_map<char, int> freq;for (char c : str) {if (('0' <= c && c <= '9') || ('A' <= c && c <= 'Z')) {freq[c]++;}}for (const auto& pair : freq) {cout << pair.first << ": " << pair.second << endl;}
}// 测试
int main() {frequency("TEST2024"); // 输出可能为:T:2, E:1, S:1, 2:1, 0:1, 4:1return 0;
}
4.std::count法,针对特定的一个字符统计频率,需遍历每一个字符类型
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;void frequency(const string& str) {string valid_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";for (char target : valid_chars) {int cnt = count(str.begin(), str.end(), target);if (cnt > 0) {cout << target << ": " << cnt << endl;}}
}// 测试
int main() {frequency("C++17"); // 输出:1:1, 7:1, C:1, +:+ (但非法字符被忽略)return 0;
}
测试数据设计
- 合法字符混合:
Input: "AAABBB12345XYZ" Expected Output: A:3, B:3, 1:1, 2:1, 3:1, 4:1, 5:1, X:1, Y:1, Z:1
- 包含非法字符:
Input: "Hello!@#456" Expected Output: 4:1, 5:1, 6:1 (忽略小写字母和符号)
- 空字符串:
Input: "" Expected Output: (无输出)