C语言统计一篇文件里出现最多的三个单词
发布网友
发布时间:2022-04-07 10:38
我来回答
共3个回答
热心网友
时间:2022-04-07 12:07
以前写过一个统计一篇文章中单词出现频率的程序,这里正好可以用(只输出前三个单词):
//统计单词出现频率
#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);
}
}追问你这也太复杂了,我就想用数组
热心网友
时间:2022-04-07 13:25
因为代码实现略长,不易展示,所以,只提供方法:
定义一个结构体数组,用来存储单词和出现次数
struct _word {
char word[100]; //假定最大单词长度为100,不足可以修改加大
int count;
} word_list[300]; //不同单词个数如超过300,可加大此值
int word_num; //数组中的单词个数
定义文件指针fp,读方式打开数据文件
循环读取单词
用fscanf("%s")读取一个单词到字符数组中(忽略标点符号,单词间以空格,TAB,回车符分开)
检查新读到的单词在word_list数组中是否存在
继续读取下一单词,若文件结束,则结束循环
对当前数组按count值从大到小排序(可采用任意一种排序方法来实现,如冒泡,选择等)
输出排好序的数组前3个数据
按以上过程实现代码,可以达到单词统计的效果。
如果需要对标点符号的处理,可在读取一个单词后,进行标点符号的检查与处理,再确定是否将数据加到单词数组中。
热心网友
时间:2022-04-07 15:00
#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;
}追问抄的滚蛋
追答不会借鉴人家的,你有什么好方法?