以前写过一个统计一篇文章中单词出现频率的程序,这里正好可以用(只输出前三个单词):
//统计单词出现频率
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Node{
int c; //单词w程序次数
char w[20]; //单词
struct Node *next;
struct Node *pre;
};
char s[]=" ,;.?!:(\"\\)['|]{/}@#$&*+-=<~`_>0123456789\12"; //单词分隔符
//在head中查找单词pw,找到flag=1,返回该结点指针;否则flag=0,返回链表尾结点指针,
struct Node *Find(struct Node *head, char *pw, int *falg);
//输出统计结果
void Print(struct Node *head);
//统计一行
void Count(struct Node *head, char *pl);
//释放链表
void Distroy(struct Node *head);
int main(){
struct Node *h;
FILE *pf;
char s[1024];
char filename[]="c:\\test.TXT";
pf=fopen(filename,"r");
if(!pf){
printf("打开文件时出错\n");
return 1;
}
h=(struct Node *)malloc(sizeof(struct Node));
h->next=h->pre=0;
h->w[0]='\0';
h->c=0;
while(fgets(s,513,pf)!=0){
Count(h, s);
}
fclose(pf);
Print(h);
Distroy(h);
return 0;
}
struct Node *Find(struct Node *head, char *pw, int *flag){
struct Node *p=head, *q=head;
while( p!=0 && strcmp(p->w, pw)!=0 ){
q=p;
p=p->next;
}
if(p==0){
*flag=0;
return q;
}else{
*flag=1;
return p;
}
}
void Print(struct Node *head){
struct Node *p=head;
int c=0;
while(p && c<3){
printf("%s: %d\n", p->w, p->c);
p=p->next;
c++;
}
}
void Count(struct Node *head, char *pl){
struct Node *p, *q;
char *pw, tw[20];
int f, tc;
strlwr(pl); //将字符串pl中的字母变为小写
pw=strtok(pl,s); //提前字符串pl中的首个单词
while(pw!=0){
q=Find(head, pw, &f);
if(f==1){ //找到该单词,出现次数加一
q->c++;
}else{ //没找到该单词,将该单词插入链表
if(q==head && q->w[0]=='\0'){ //原链表为空,这是第一个单词
strcpy(q->w, pw);
q->c=1;
q->next=q->pre=0;
}else{ //链表不空,将该单词插入链表尾部
p=(struct Node *)malloc(sizeof(struct Node));
p->next=0;
p->pre=q;
strcpy(p->w, pw);
p->c=1;
q->next=p;
}
} //没找到该单词
//调整单词次序
p=q;
while(p!=head && p->c > (p->pre)->c)
p=p->pre;
//交换p和q两结点的数据(单词及出现次数)
if(p!=q){
strcpy(tw, p->w);
strcpy(p->w, q->w);
strcpy(q->w, tw);
tc=p->c;
p->c=q->c;
q->c=tc;
}
pw=strtok(0,s); //提前字符串pl中的下一个单词
}
}
void Distroy(struct Node *head){
struct Node *p=head, *q;
while(p){
q=p;
p=p->next;
free(q);
}
}
追问你这也太复杂了,我就想用数组