- 问题描述
密码分析学中常常需要统计字符出现的频度。给定若干行短文,要求按字符出现的频度由高到低输出,当两个字符出现的频度相同时,按字符大小的顺序输出。
注意:只需要统计英文字母的频度,非英文字母一律忽略。
- 输入说明
输入由多组数据组成。每组数据由一行长度不超过100的字符串组成,不区分字母大小写,如A与a看作同一个字母。 - 输出说明
对每组输入数据都有若干行输出,每行有两个输出数据,第一个数据为某个大写字母,第二个数据为该字母出现的频度,两个数据之间有一个空格。输出顺序按字母出现的频度由高到低输出,当两个字母的频度相同时,按字母大小的顺序输出。两组输出之间有一行空行。 - 输入范例
cpp
Do what you say, say what you do.
This is a test.
Count me 1 2 3 4 5.
- 输出范例
cpp
A 4
O 4
Y 4
D 2
H 2
S 2
T 2
U 2
W 2
S 3
T 3
I 2
A 1
E 1
H 1
C 1
E 1
M 1
N 1
O 1
T 1
U 1
感想:将输入的每一行的字母都转为大写字母,使用辅助数组统计26个字母的各个字母的数量,再将辅助数组里的值赋给使用结构体的数组;按要求排序,输出。
代码如下:
cpp
#include <bits/stdc++.h>
using namespace std;
struct Letter {
char alphar;
int count;
};
bool compare(const Letter& a,const Letter &b) {
if(a.count != b.count)
return a.count > b.count;
return a.alphar < b.alphar;
}
vector<Letter> toUpperAndCnt(const string & s) {
vector<int> arr(26,0);
char ch;
for(const char& c : s) {
if(isalpha(c)) {
ch = toupper(c);
++arr[ch-'A'];
}
}
Letter letter;
vector<Letter> target;
for(int i = 0; i<26; ++i) {
if(arr[i]!=0) {
letter.alphar = 'A' + i;
letter.count = arr[i];
target.push_back(letter);
}
}
return target;
}
int main() {
string input;
while(getline(cin,input)) {
vector<Letter> target = toUpperAndCnt(input);
sort(target.begin(),target.end(),compare);
for( const auto & ele : target ) {
cout<<ele.alphar<<" "<<ele.count<<endl;
}
cout<<endl;
}
return 0;
}