1、代码来源:http://www.cnblogs.com/meihao1203/p/6798368.html (作者:正在加载.......)
2、Windows平台,C语言,VC6.0运行环境
3、关于代码的修改:有bug,该程序可以实现输出出现频率最高的10个单词,但是对于如果出现频率最高的单词数小于10,则系统会报错。修改:由于是用for循环输出高频率单词的相关信息,所以采用判断该数组是否为零,不为0,则输出该单词和出现的次数。关于输入文件名的情况也进行了修改,采用提示用户输入文件名,并判断是否能够打开,能则继续运行,否则就提示。
4、GitHub的代码地址:https://github.com/Yu0Ci/Project/blob/master/WC.txt
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 30
typedef struct node
{
char s[30];
struct node* next;
int count;
}node,*List;
int FindInDict(node **dict,char *s);
void InsertToDict(node **dict,char *s);
void FindTop(node *dict,List top[],int n);
int main()
{
FILE *fp;
char filename[100];
char ch;
char word[30];
int len=0;
int c_ch=0;
int c_line=0 ;
int c_word=0;
node *dict =(node *)calloc(26,sizeof(node)); //定义动态数组,存放的是相应单词的头结点
node *top[10]={0}; //存放排名前十的单词的指针(内存地址)
int i=0;
printf("请输入文件名:");
gets(filename);
if((fp=fopen(filename,"r"))==NULL)
{
printf("不能打开文件\n",filename);
getchar();
exit(1);
}
fseek(fp,0,SEEK_SET);
while((ch=fgetc(fp))!=EOF)
//注意这里必须(ch=fgetc(fp)),因为!=优先级高,先算!=结果为1,不加()结果ch=1
{
c_ch++;
len=0;
while(ch>='a'&&ch<='z')
{
word[len++]=ch;
ch=fgetc(fp);
c_ch++;
}
if(len!=0)
{
word[len]='\0';
c_word++;
if(FindInDict(&dict,word)==0)
InsertToDict(&dict,word);
}
if(ch=='\n')
c_line++;
}
printf("the number of character is:%d\n", c_ch);
printf("the number of line is:%d\n", c_line+1 );
printf("the number of word is:%d\n", c_word);
FindTop(dict,top,10);
for(i=0;i!=10;++i)
{
if(top[i]!=0)
printf("the top %2d word is %-10s, %d\n", i + 1, top[i]->s, top[i]->count);
}
fclose(fp);
return 0;
}
int FindInDict(node **dict,char *s)
{
int index=(s[0]-'a');
node *p=((*dict)+index)->next;
while(p!=NULL)
{
if(strcmp((p->s),s)<0)
p=p->next;
else
{
if(strcmp(p->s,s)>0)
return 0;
else
{
p->count++;
return 1;
}
}
}
return 0;
}
void InsertToDict(List *dict,char *s)
{
int index=(s[0]-'a');
node *p=(*dict+index)->next;
node *word=(node *)malloc(sizeof(node));
word->count=1;
strcpy(word->s,s);
word->next=NULL;
if(NULL==p)
{
(*dict+index)->next=word;
}
else
{
if(strcmp(s,p->s)<0)
{
word->next=p;
(*dict+index)->next=word;
return;
}
while(p->next!=NULL)
{
if(strcmp(s,p->next->s)<0)
{
word->next=p->next;
p->next=word;
return;
}
else
p=p->next;
}
if(p->next!=word)
p->next=word;
}
}
int cmp(const void *a,const void *b) //List数组中任意两个元素的地址
{
List *i=(List*)a; //强制转换
List *j=(List*)b;
return ((*j)->count-(*i)->count);
}
void FindTop(List dict,List top[],int n)
{
node *p=dict;
node *q=p->next;
node *tmp[100000]={0};
int i,index=0;
while(p<dict+26)
{
while(q!=NULL)
{
tmp[index++]=q;
q=q->next;
}
p++;
q=p->next;
}
qsort(tmp,index,sizeof(List),cmp);//排序函数
for(i=0;i<n;++i)
top[i]=tmp[i];
}