软工作业:高频词汇
题目:给一个文本文件,找出频率最高的十个词
2014.2.26
分析:
可用开发环境 :VC++ 6.0 、java、c#
找出频率最高的词简单设计思路:
1、输入文本,读取文本,由字母开始,到第一个非字母终止时存储一个单 词。
2、将大写字母改为小写才能进行比较。
3、每存储一个单词要与前面的单词做比较,若已存在则对应数量加一。
4、用两个数组,分别存放单词及其对应数目。
5、按单词数目由大到小排序,找出前十个,输出对应单词。
尝试用较为熟悉的c++编程:
定义一个数组结构Word存储单词,每个单词有个数num 和用于存储单词的数组a[]属性。
函数:读取文件并存储单词及其个数 readfile();按个数排序 sortWord();主函数 main();
问题:
对我来说按字符读取文件不太熟悉,比较难。一开始做的程序比较粗糙,没有读取文件而是按字符直接输入,能运行但是结果不正确,出现许多问题。
2014.3.1
重新翻看c++课本复习了一遍读取文本的方法,通过FILE结构进行文件操作。
程序运行中出现问题,做了多次更改,进一步完善程序。
最终代码如下(曾出问题处用★标注):
1 #include<iostream.h> 2 #include<stdlib.h> //★ 3 #include<stdio.h> 4 #include<string.h> 5 #define MAX 500 6 struct WORD 7 { 8 int num; 9 char a[20]; 10 };//定义结构体数组用于保存单词及出现的个数 11 int main() 12 { 13 WORD A[MAX]; 14 FILE *in; 15 char ch; 16 int i=0,j=0,m,n; 17 char infile[20]; 18 cout<<"输入文件路径"<<endl; 19 cin>>infile;//输入文件名字 20 if((in=fopen(infile,"r"))==NULL) 21 { 22 cout<<"此文件无法打开"; 23 exit(0); 24 } 25 for(i=0;i<MAX;i++) { A[i].num=1;} //所有单词数目初始化为1 26 i=0; 27 int word=0;//★word用处是防止将‘ ’等认为单词 28 while(!feof(in)) 29 { 30 A[i].a[j]='\0';//单词结束的标志是\0.★此句不用会在单词结束出现乱码 31 ch=fgetc(in); 32 if(ch>='A'&&ch<='Z') {ch+=32;}//将大写字母换成小写字母 33 if((ch==' '||ch==','||ch=='.')&&word==1)//判断单词结束
//★之前用的判断方法是!(ch>='a'&&ch<='z'),忽略了 ‘ -等用在单词中的隔断符,以至于出现’s‘这样的单词 34 { 35 j=0; 36 n=i; 37 i++;//结构体数组加1 38 word=0; 39 if(n>=1)//比较单词是否已经出现过 40 { 41 for(m=0;m<n;m++) 42 { 43 if(strcmp(A[n].a,A[m].a)==0) 44 { 45 A[m].num++; 46 i-=1;//结构体数组恢复原位 47 } 48 } 49 } 50 } 51 else if((ch==' '||ch==','||ch=='.')&&word!=1) continue;//★ 52 else if(ch>='a'&&ch<='z') 53 { 54 A[i].a[j]=ch; 55 j++; 56 word=1; 57 } 58 } 59 int t1; 60 char t2[20]; 61 for(i=0;i<MAX;i++)//按单词数目从大到小排序 62 { 63 for(j=i+1;j<MAX;j++) 64 if(A[j].num>A[i].num) 65 { 66 t1=A[j].num;A[j].num=A[i].num;A[i].num=t1; 67 strcpy(t2,A[j].a); strcpy(A[j].a,A[i].a); strcpy(A[i].a,t2); 68 } 69 } 70 cout<<"单词\t\t出现次数"<<endl; 71 for(i=0;i<10;i++) //显示出频率最高的前10个单词,及出现次数 72 { 73 cout<<A[i].a<<"\t\t"<<A[i].num<<endl; 74 } 75 return 0; 76 }
运行结果: