请编写程序,对一段英文文本,统计其中所有不同单词的个数,以及词频最大的前10%的单词。
所谓“单词”,是指由不超过80个单词字符组成的连续字符串,但长度超过15的单词将只截取保留前15个单词字符。而合法的“单词字符”为大小写字母、数字和下划线,其它字符均认为是单词分隔符。
输入格式:
输入给出一段非空文本,最后以符号
#
结尾。输入保证存在至少10个不同的单词。输出格式:
在第一行中输出文本中所有不同单词的个数。注意“单词”不区分英文大小写,例如“PAT”和“pat”被认为是同一个单词。
随后按照词频递减的顺序,按照
词频:单词
的格式输出词频最大的前10%的单词。若有并列,则按递增字典序输出。输入样例:
This is a test. The word "this" is the word with the highest frequency. Longlonglonglongword should be cut off, so is considered as the same as longlonglonglonee. But this_8 is different than this, and this, and this...# this line should be ignored.
输出样例:(注意:虽然单词
the
也出现了4次,但因为我们只要输出前10%(即23个单词中的前2个)单词,而按照字母序,the
排第3位,所以不输出。)23 5:this 4:is
思路:在读入文本的时候直接把所有的字符转成小写,然后把符号变成空格,这样就可以在stringstream中直接按照空格切割,这样不管是 This 还是 “this” 还是 ,this' 最后都会变成 this 非常巧妙的思路。
坑点分析:
1.超过15字符的单词要截掉多余部分,直接丢弃不用管。
2.处理过程中碰到 # 要!直!接!退!出!!!。
3.输出的时候先输出一行不同的词个数,善于利用PTA在线调试找不同。
4.计算10%的词语是算不同的词语个数,重复的只算一次。
5.输入要用getline(cin,s)一行一行读取。
超详细讲解AC代码附上:
#include<bits/stdc++.h>
using namespace std;
struct node{//用来存关键词和出现次数
string name;
int num;
}lst[100086];
bool cmp(node a,node b){//输出排序规则
if(a.num!=b.num )return a.num >b.num;
return a.name <b.name ;
}
int cheak(char c){//检查是不是符号
if(c>='a'&&c<='z')return 1;
if(c>='A'&&c<='Z')return 1;
if(c>='0'&&c<='9')return 1;
if(c=='_' ||c=='#')return 1;
return 0;
}
int main(){
string s;
map<string,int>mp;
int flag = true;//用来标记是否结束输入
while(getline(cin,s) &&flag){
for(int i=0;i<s.length();i++){
if(cheak(s[i])==0){
s[i]=' ';//把符号换成空格 特判 # _ 不处理
}
if(s[i]>='A'&&s[i]<='Z'){
s[i] = s[i]-'A'+'a';//转小写
}
}
string s1;
stringstream ss(s);//用字符串流分割空格,处理单词
while(ss>>s1){
if(s1=="#"){//碰到#就结束输入
flag = false;
break;
}
int len = s1.length();
if(len>15){//单词大于15个就截取
s1 = s1.substr(0,15);
}
len = s1.length();
mp[s1]++;//用map标记,去重+快速
}
}
cout<<mp.size()<<endl;//输出有多少个不同的关键词
int cnt=0;
for(auto it:mp){
//把map里的数据倒到结构体里面排序输出,
lst[cnt].name = it.first;
lst[cnt].num = it.second;
cnt++;
}
sort(lst,lst+cnt,cmp);
//排序
int sl = cnt*0.1;//要输出的数量 10% = 0.1
for(int i=0;i<sl;i++){
cout<<lst[i].num<<":"<<lst[i].name<<endl;
}
return 0;//别忘记return 0; (说的就是你小林)
}
求个关注