如何在C++中对结构体排序并降序输出字符统计结果?
问题:统计文件字母出现次数并按次数降序排序输出
我的input.txt文件中有类似如下句子:
HELLO COUNT HOW MANY CHARACTERS ARE HERE AND WHICH CHARACTERS
我需要读取该文件,统计每个字母的出现次数,再将这些字母按出现次数降序排序后输出(次数相同时字母顺序不限)。例如统计结果为H:7, E:6, L:2, O:3, C:5, W:2, A:7, Y:1, R:6, S:2, I:1, M:1, N:1,排序后应为H:7, A:7, E:6, R:6, C:5, O:3, L:2, W:2, S:2, Y:1, I:1, M:1, N:1。
我是C++新手,不知道如何实现排序及按序输出。我想到用struct来存储字母数据,但进展不顺,以下是我的代码:
#include <iostream> #include <fstream> #include <string> #include <algorithm> using namespace std; struct letters{ int A=0, C=0, E=0, H=0, I=0, L=0, M=0, N=0, O=0, R=0, S=0, W=0, Y=0; int n=13; }; int main() { string str; int A=0, C=0, E=0, H=0, I=0, L=0, M=0, N=0, O=0, R=0, S=0, W=0, Y=0; int n=13; // How many letters there are in total ifstream read("input.txt"); while (getline(read,str)) { for(char &ch : str) { // Here I read a letter and if it matches one of those "if statements" it counts it if(ch == 'A'){ A++; } if(ch == 'C'){ C++; } if(ch == 'E'){ E++; } if(ch == 'H'){ H++; } if(ch == 'I'){ I++; } if(ch == 'L'){ L++; } if(ch == 'M'){ M++; } if(ch == 'N'){ N++; } if(ch == 'O'){ O++; } if(ch == 'R'){ R++; } if(ch == 'S'){ S++; } if(ch == 'W'){ W++; } if(ch == 'Y'){ Y++; } } } letters a[n]; sort(a, a+n); // Trying to sort it and then print everything out like I did below. But I don't know how // Here I just check if every letter is counted correctly cout << "A: " << A << endl; cout << "C: " << C << endl; cout << "E: " << E << endl; cout << "H: " << H << endl; cout << "I: " << I << endl; cout << "L: " << L << endl; cout << "M: " << M << endl; cout << "N: " << N << endl; cout << "O: " << O << endl; cout << "R: " << R << endl; cout << "S: " << S << endl; cout << "W: " << W << endl; cout << "Y: " << Y << endl; read.close(); return 0; }
解决方案
你的核心问题是结构体设计错误:原letters结构体把所有字母的计数都存在一个对象里,这样无法用sort排序。正确的做法是用结构体存储单个字母+对应计数,再把所有字母的统计项放进容器里排序。
修改后的完整代码
#include <iostream> #include <fstream> #include <string> #include <algorithm> #include <vector> using namespace std; // 单个字母的统计项:字符+出现次数 struct CharCount { char c; int count; // 构造函数,初始化字符和初始计数0 CharCount(char ch) : c(ch), count(0) {} }; int main() { string str; // 初始化需要统计的字母列表,用vector存储所有统计项 vector<CharCount> charList = { 'A', 'C', 'E', 'H', 'I', 'L', 'M', 'N', 'O', 'R', 'S', 'W', 'Y' }; ifstream read("input.txt"); if (!read.is_open()) { // 检查文件是否成功打开 cerr << "无法打开input.txt文件" << endl; return 1; } // 读取文件内容并统计次数 while (getline(read, str)) { for (char ch : str) { // 遍历统计列表,找到对应字母就累加计数 for (auto& item : charList) { if (item.c == ch) { item.count++; break; // 找到后直接跳出循环,提升效率 } } } } read.close(); // 按出现次数降序排序:次数大的在前,次数相同则顺序不限 sort(charList.begin(), charList.end(), [](const CharCount& a, const CharCount& b) { return a.count > b.count; }); // 输出排序后的结果,格式和示例一致 cout << "排序后的统计结果:" << endl; bool first = true; for (const auto& item : charList) { if (!first) { cout << ", "; } cout << item.c << ":" << item.count; first = false; } cout << endl; return 0; }
关键部分解释
- 结构体重构:
CharCount结构体只存单个字母和它的计数,这样每个字母对应一个结构体对象,方便排序。 - 容器选择:用
vector<CharCount>存储所有统计项,比原生数组更灵活,也符合C++的现代用法。 - 统计逻辑优化:遍历文件字符时,直接在统计列表中匹配对应字母累加,替代原代码中大量重复的
if判断。 - 排序规则:用lambda表达式给
sort自定义比较规则,a.count > b.count实现降序排序;如果需要次数相同时按字母升序,可改为a.count != b.count ? a.count > b.count : a.c < b.c。 - 输出格式:处理第一个元素不需要前置逗号,保证输出格式和示例一致。
内容的提问来源于stack exchange,提问作者user20832627
相关产品推荐
相关产品推荐

