BUAA(2021春)词频统计(数组或链表实现)

48 篇文章 154 订阅

看前须知

要点介绍和简要声明.

第三次上机题汇总

连续线段——结构体多级排序.

猴子选大王(约瑟夫问题)+3种解决约瑟夫问题的方法.

多项式相乘.

文件加密(环)——要求循环链表熟练的删除操作.

词频统计(数组或链表实现).

题目内容

问题描述

编写程序统计一个英文文本文件中每个单词的出现次数(词频统计),并将统计结果按单词字典序输出到屏幕上。

注:在此单词为仅由字母组成的字符序列。包含大写字母的单词应将大写字母转换为小写字母后统计。

输入形式

打开当前目录下文件“article.txt”,从中读取英文单词进行词频统计。

输出形式

程序将单词统计结果按单词字典序输出到屏幕上,每行输出一个单词及其出现次数,单词和其出现次数间由一个空格分隔,出现次数后无空格,直接为回车。

样例

【样例输入】

当前目录下文件article.txt内容如下:

“Do not take to heart every thing you hear.”

“Do not spend all that you have.”

“Do not sleep as long as you want;”

【样例输出】

all 1

as 2

do 3

every 1

have 1

hear 1

heart 1

long 1

not 3

sleep 1

spend 1

take 1

that 1

thing 1

to 1

want 1

you 3

样例说明

按单词字典序依次输出单词及其出现次数。

题解

易错点和难点

本题不难,结构化处理即可。
首先是读入文章,然后是读取单词,这一块需要一点操作,先确定单词的开头,之后从该字母向后寻找非字母的元素,确定单词的结尾,然后拷贝进结构体,同时越过单词,继续确定单词。一定要去重,最后输出。

参考代码

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
struct vocabCount{ //词频结构体 
	char word[200];//单词 
	int times;     //词频 
};
typedef struct vocabCount V;
char s[200],tmp[200],ch;
int i,j,k,cnt=0;
V a[1000];
int cmp(const void*p1,const void*p2);
void GetArticle(FILE *fp1); //读取文章 
void GetWord(FILE *fp1);    //读取单词 
void DelRepeated(FILE *fp1);//去重 
void Output(FILE *fp1);     //输出 
int main()
{	
	FILE *fp1 = fopen("article.txt","r");
	GetArticle(fp1);	//读取文章 
	GetWord(fp1);		//读取单词 
	DelRepeated(fp1);	//去重 
	Output(fp1);		//输出 
	return 0;
}
int cmp(const void*p1,const void*p2) //根据字典序排序 
{
	struct vocabCount *a=(struct vocabCount*)p1;
	struct vocabCount *b=(struct vocabCount*)p2;
	return strcmp(a->word,b->word);
}
void GetArticle(FILE *fp1)
{
	ch=fgetc(fp1);
	i=0;
	while(ch!=EOF)
	{
		s[i]=ch;
		i++;
		ch=fgetc(fp1);
	}
	for(i=0;i<strlen(s);i++)
	{
		if(isalpha(s[i])) s[i]=tolower(s[i]); //全部转化为小写 
	}
}
void GetWord(FILE *fp1)
{
	for(i=0;i<strlen(s);i++)
	{
		if(isalpha(s[i])) //如果是字母,确定为单词开头 
		{
			for(j=i;j<strlen(s);j++)
			{
				if(!isalpha(s[j])) //遇到非字母的元素 
				{
					break;
				}
			}
			memset(tmp,0,sizeof(tmp));
			for(k=0;k<j-i;k++)
			{
				tmp[k]=s[i+k];   //存储单词 
			}
			strcpy(a[cnt].word,tmp); //拷贝单词 
			cnt++;
			i=j;
		}
		else	continue;
	}
	qsort(a,cnt,sizeof(V),cmp); //排序 
	for(i=0;i<cnt;i++) a[i].times=1;
}
void DelRepeated(FILE *fp1)
{
	for(i=0;i<cnt;i++)
	{
		if(strcmp(a[i].word,a[i+1].word)==0) //重复 
		{
			a[i+1].times+=a[i].times;//频率加一 
			a[i].times=0;
		}
	}
	qsort(a,cnt,sizeof(V),cmp);
}
void Output(FILE *fp1)
{
	for(i=0;i<cnt;i++)
	{
		if(a[i].times==0)
		{
			continue;
		}
		else
		{
			printf("%s %d\n",a[i].word,a[i].times);
		}
	}
}

补充测试的数据

如果分部处理都正确,则不会出现太大的问题。

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值