看前须知
第三次上机题汇总
题目内容
问题描述
编写程序统计一个英文文本文件中每个单词的出现次数(词频统计),并将统计结果按单词字典序输出到屏幕上。
注:在此单词为仅由字母组成的字符序列。包含大写字母的单词应将大写字母转换为小写字母后统计。
输入形式
打开当前目录下文件“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);
}
}
}
补充测试的数据
如果分部处理都正确,则不会出现太大的问题。