关于一个文本文件中的单词统计和排序问题
题目是:写一个程序,分析一个文本文件中各个单词出现的频率,并且把频率最高的10个词打印出来。
看到题目后,我首先在纸上把需要实现的功能和需要涉及到的知识写出来,需要实现的功能是读取文本文件,记录各个单词出现的次数,利用排序将前十个单词输出。涉及的知识是文本文件的打开以及读写操作,排序算法等。
我一开始的设想是在主函数中包含两个函数,一个读取文件中的字符,并且进行统计的函数,第二个就是排序的函数。在代码实现的过程中,文件的打开关闭,读取功能可以实现。排序功能过也能容易地实现,不过在统计时的字符串和结构体的相关操作不熟悉,整个程序没有能独立实现。于是我从网上借鉴了大神们的编程思想,用的C语言中的一些知识。包括文件的操作,指针的应用,结构体的定义等等。下面说说的我的具体实现过程和从借鉴的过程中学到的知识:
首先是要利用C语言读取文件,然后读取一个个的单词,并进行统计它们出现的频率。在这个过程中,为了防止标点符号也被读入到单词中,导致单词的数据统计有误,所以采用了一个字符一个字符读取的方法,同时将字符限定在'a--z','A--Z'之间,这样单词的统计以及大小写就不会出错了 。
然后就是对单词进行排序,选出十个频率最高的单词,并打印出来。 在排序问题上,因为要保持单词与频率的一致性,所以并没有采用冒泡法来进行排列,而是用频率与数组中存储的十个单词频率进行比较,如果比数组中的大,则将其列入数组,并将数组中本来的那个置为零,这样每次都可以只取最大的那个。
在编程的过程中,明白了指针和结构体的结合后可以简化很多操作步骤,读取字符的时候直接取q=q->next;即可;在文件方面也学到了很多知识,比如在C语言中文件的操作方面,文件打开和文件的读写。
下面是具体的代码:
#include<stdio.h> #include<stdlib.h> #include<ctype.h> #include<string.h> #include<fstream.h> struct word{ //单词的结构体 char name[30]; int num; struct word *next; }; void readfile(struct word*&head)//从文件中读取单词并统计出现次数 { FILE *fp; if((fp=fopen("test.txt","r"))==NULL) { printf("无法打开此文件!\n"); exit(0); } char ch,temp[30]; struct word *p; while(!feof(fp)) { int i=0; ch=fgetc(fp); temp[0]=' '; while((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||temp[0]==' ') { if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z') { temp[i]=ch; i++; } ch=fgetc(fp); if(feof(fp)) break; } temp[i]='\0'; p=head->next; while(p) { if(!_stricmp(temp,p->name)) { p->num++;break; } p=p->next; } if(!p&&temp[0]!='\0') { p=new word; strcpy(p->name,temp); p->num=1; p->next=head->next; head->next=p; } } } void sort(struct word*&head) //排序 { struct word *q; int a[10],i; for(i=0;i<10;i++) a[i]=0; printf("文章中出现频率最高的十个单词如下:\n"); for(i=0;i<10;i++) { q=head; while(q!=NULL) { if(q->num>a[i]) a[i]=q->num; else q=q->next; } q=head; while(q!=NULL) { if(a[i]==q->num) { q->num=0; printf("出现频率:%d\t",a[i]); puts(q->name); break; } else q=q->next; } } } void main() //主函数 { struct word *head; head=new word; head->next=NULL; readfile(head); sort(head); }