词频统计程序要求:
基本要求:
(1)可导入任意英文文本文件
(2)统计该英文文件中单词数和各单词出现的频率(次数),并能将单词按字典顺序输出。
(3)将单词及频率写入文件。
首先定义结构体,初始化,主函数等
typedef struct Word //字典树的结构体定义 { Word *next[MAX]; //数组下标0-25代表小写字母,26代表其他字符 int num; }; typedef struct tlist //结构体定义:单词和对应频率 { char word[200]; int time; }; struct tlist list[5000000]; //定义结构体数组 Word *root; char str[200]=""; //字符数据初始化为空 char tempword[1000]; int size=0; //size为一篇文章中字符串的个数 void output(); void display(); int main();
建立新的单词库的函数
void createWord(char *str) //新建单词库 { int len = strlen(str), id; //strlen函数是测量字符串长度的函数 Word *p = root, *q; for(int i = 0; i < len; i ++)//遍历单词判断当前字符是否为字母或其他字符 { if(str[i] >= 'a' && str[i] <= 'z') id = str[i] - 'a'; //字符相减为对应ASCII值相减 if(str[i] >= 'A' && str[i] <= 'Z') id = str[i] - 'A'; if(str[i] == '\'') id = 26; //当读取到的字符为26个英文字母除外的其他字符,id置为26 if(p->next[id] == NULL) //若已到达链表结尾,开辟新的结构体存入字母 { q = (Word *)malloc(sizeof(Word)); for(int j = 0; j < MAX; j ++) { q->num=0; q->next[j] = NULL; } p->next[id] = q; p = p->next[id]; } else //若未到达链表结尾,指针指向下一个 { p = p->next[id]; } } p->num++; //重复单词数加1 }
读库内的函数
void readWord(Word *p,int len) //读单词的函数 { int i; for(i=0;i<27;i++) { if(p->next[i]!=NULL) { if (i==26) { str[len+1]='\0'; str[len]='\''; len++; } else { str[len]='a'+i; len++; } readWord((Word*)p->next[i],len); len--; } } if(p->num!=0) { str[len]='\0' ; strcpy(list[size].word,str); //如果遇到单词结束标志,将str存入list[size].word list[size].time=p->num; size++; } }
输出函数
void output() //输出函数 { int i; FILE *fpx; fpx=fopen("result.txt","w"); //将统计结果写入到result.txt文件中 for (i=1;i<size;i++) fprintf(fpx,"%s %d\n",list[i].word,list[i].time); for (i=1;i<size;i++) //输出统计结果 printf("%s %d\n",list[i].word,list[i].time); fclose(fpx); }
输出菜单
void menu() //菜单函数 { int choose; printf("-------------------------------------------------------\n\n"); printf("【 英文单词词频统计 】\n\n"); printf("【 请在文本文档data.txt中输入英文单词或者英文文章 】\n"); printf("【 】\n\n"); printf("【 请按数字键1查看词频统计结果 】\n"); printf("-------------------------------------------------------\n\n"); scanf("%d",&choose); if(choose==1) display(); }
将输入的英文写入在result中
void display() //将读入的文件输入到result中 { int i,j; char x; int len=0; //初始时字符串长度为0 root=(Word*)malloc(sizeof(Word)); //为结构体指针root动态开辟存储空间 for (i=0;i<27;i++) root->next[i]=NULL; FILE *fp; fp=fopen("data.txt","r"); //文件打开方式为只读 if(!fp) { printf("\n打开文件data.txt失败!"); }while((x=fgetc(fp))!=EOF) //从txt文档中读入 读入失败时,函数值为EOF(-1) fgetc为从文件中读取一个字符 { if ((x>='A'&&x<='Z')||(x>='a'&&x<='z')||(x=='\''&&len!=0)) { tempword[len]=x; len++; } else { tempword[len]='\0'; createWord(tempword); len=0; } } tempword[len]='\0'; createWord(tempword); //创建对文本最后一个英文字符串的读取 len=0; fclose(fp); readWord(root,0); struct tlist temp; for(i=0;i<size-1;i++) //比较频率大小冒泡排序 for(j=i+1;j<size;j++) if(list[i].time>list[j].time||(list[i].time==list[j].time&&strcmp(list[i].word,list[j].word)>0)) { temp.time=list[i].time; list[i].time=list[j].time; list[j].time=temp.time; strcpy(temp.word,list[i].word); strcpy(list[i].word,list[j].word); strcpy(list[j].word,temp.word); } printf("英文单词及词频统计结果如下:\n"); output(); }
主函数
int main() //主函数 { menu(); return 0; }
在调试的过程中,一开始总出现错误:“打开文件错误”
经检查过后发现,是由于data.txt文件和result.txt文件没有添加到正确位置,后加入工作区间中,如下
然后便能运行出结果了。