碰到这个题目我的思路是采用键值对的方式实现,出现的新的字符就作为键,出现的次数为值,最终形成一个键值对列表,比如按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-Z
for (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:1
return 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:1
return 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:1
return 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: (无输出)