C语言统计一篇文件里出现最多的三个单词

使用c语言编程,统计出自己创建的一篇文件(300字以内)中的出现次数最多的三个单词,以及这三个单词的出现的次数,

以前写过一个统计一篇文章中单词出现频率的程序,这里正好可以用(只输出前三个单词):
//统计单词出现频率
#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);
}
}追问

你这也太复杂了,我就想用数组

温馨提示:答案为网友推荐,仅供参考
第1个回答  2015-09-19

因为代码实现略长,不易展示,所以,只提供方法:

    定义一个结构体数组,用来存储单词和出现次数

    struct _word {

    char word[100]; //假定最大单词长度为100,不足可以修改加大

    int count;

    } word_list[300]; //不同单词个数如超过300,可加大此值

    int word_num; //数组中的单词个数

    定义文件指针fp,读方式打开数据文件

    循环读取单词

    用fscanf("%s")读取一个单词到字符数组中(忽略标点符号,单词间以空格,TAB,回车符分开)

    检查新读到的单词在word_list数组中是否存在

      不存在,则将单词记入数组中,count=1,word_num+1

      存在,则将该单词的count+1

    继续读取下一单词,若文件结束,则结束循环

    对当前数组按count值从大到小排序(可采用任意一种排序方法来实现,如冒泡,选择等)

    输出排好序的数组前3个数据

按以上过程实现代码,可以达到单词统计的效果。

如果需要对标点符号的处理,可在读取一个单词后,进行标点符号的检查与处理,再确定是否将数据加到单词数组中。

第2个回答  2015-01-06
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

const int MAXSIZE = 128; // 每个单词不超过128个字符

typedef struct node {
char word[MAXSIZE];
int size;
struct node *next;
}*List,*pNode;

List Init() {
List head;
head = (pNode)malloc(sizeof(struct node));
head->size = 0;
head->word[0] = '\0';
head->next = NULL;
return head;
}

char *toLower(char s[]) { // 小写变大写
int i = 0;
while(s[i]) {
if(s[i] >= 'A' && s[i] <= 'Z')
s[i] += 'a' - 'A';
++i;
}
return s;
}

void Add(List head,char s[]) { // 添加到链表中
pNode p = head;
char t[MAXSIZE];
strcpy(t,toLower(s));
while(p->next) {
if(strcmp(p->next->word,t) == 0) {
++p->next->size;
return;
}
p = p->next;
}
p->next = (pNode)malloc(sizeof(struct node));
strcpy(p->next->word,t);
p->next->size = 1;
p->next->next = NULL;
}

void Sort(List head) { // 根据各个词的数量排序(大到小)
pNode p,q,qt;
char ct[MAXSIZE];
int it;
for(p = head; p->next; p = p->next) {
qt = p;
for(q = p->next; q->next; q = q->next) {
if(strlen(qt->next->word) < strlen(q->next->word))
qt = q;
}
if(p != qt) {
strcpy(ct,p->next->word);
strcpy(p->next->word,qt->next->word);
strcpy(qt->next->word,ct);
it = qt->next->size;
qt->next->size = p->next->size;
p->next->size = it;
}
}
}

void Show(List head, int n,FILE *fp) { // 显示前n个
int i;
pNode p = head->next;
for(i = 0; p; ++i) {
fprintf(fp,"%s\n",p->word);
if(i < n) printf("%3d : %s\n",p->size,p->word);
p = p->next;
}
}

int main() {
char word[MAXSIZE];
List head = Init();
FILE *fin = fopen("data.txt","rt");
FILE *fout = fopen("result.dat","wt");
List list = Init();
if(fin == NULL || fout == NULL) {
printf("不能打开数据文件。\n");
return 1;
}
while(fscanf(fin,"%s",word) == 1)
Add(head,word);
fclose(fin);
Show(head,3,fout);
fclose(fout);
return 0;
}追问

抄的滚蛋

追答

不会借鉴人家的,你有什么好方法?

相似回答