问题描述 :
密码分析学中常常需要统计字符出现的频度。给定若干行短文,要求按字符出现的频度由高到低输出,当两个字符出现的频度相同时,按字符大小的顺序输出。
注意:只需要统计英文字母的频度,非英文字母一律忽略。
输入说明 :
输入由多组数据组成。每组数据由一行长度不超过100的字符串组成,不区分字母大小写,如A与a看作同一个字母。
输出说明 :
对每组输入数据都有若干行输出,每行有两个输出数据,第一个数据为某个大写字母,第二个数据为该字母出现的频度,两个数据之间有一个空格。输出顺序按字母出现的频度由高到低输出,当两个字母的频度相同时,按字母大小的顺序输出。两组输出之间有一行空行。
输入范例 :
Do what you say, say what you do.
This is a test.
Count me 1 2 3 4 5.
输出范例:
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
总结
1.这个题和基础题64统计子母有点类似,有些不同就是需要按照频度输出。其实不用结构体也能做出来,只要在64的基础上进行个排序就可以,既然出现在结构体这里,倒不如构造个。我的思路基本上很清楚:
用字符数组保存字符串---->进行是否为子母的判断----->如果为子母统一化成大写子母----->用结构数组保存字符串中字符出现的频度(初始频度均为0,每次出现一个字符充分利用字符与数字之间的关系进行频度的统计)---->按照频度进行排序----->输出频度大于0的即可
2.这里充分利用了一些函数,isalpha(),islower(),strlen();
3.加油!!
#include<stdio.h>
#include<string.h>
#include<ctype.h>
typedef struct count{
char c;
int num;
}COUNT;
int main(){
COUNT count[26];
COUNT key;
char str[101],ch;
int len,i,j;
while(gets(str)){
len=strlen(str);
//先初始化,每个字符出现的频度均设为0
for(i=0;i<26;i++){
count[i].c='A'+i;
count[i].num=0;
}
//进行判断是否为子母并计算每个字符出现的频度
for(i=0;i<len;i++){
ch=str[i];
if(isalpha(ch)){
if(islower(ch))
ch-=32;
count[ch-'A'].num++;
}
}
//按照频度进行排序从大到小
for(i=1;i<26;i++){
if(count[i].num>count[i-1].num){
key=count[i];
for(j=i-1;j>=0 && count[j].num<key.num;j--)
count[j+1]=count[j];
count[j+1]=key;
}
}
//输出频度大于0的即可
for(i=0;i<26;i++){
if(count[i].num>0){
printf("%c %d\n",count[i].c,count[i].num);
}
}
printf("\n");
}
return 0;
}