题目:写一个程序,分析一个文本文件(英文文章)中各个词出现的频率,并且把频率最高的10个词打印出来。

基本思路:我看到这个题目的时候,想到程序的功能是分析各个词出现的频率,所以关键问题就是讲文件中的字符组成的单词分离出来,然后去进行分析。所以我的设计思路是将程序分为三个模块,第一个模块儿是将文件中的字符读入程序并分离出一个个单词;第二个模块儿是将单词进行处理分析,检查是否已经有相同的单词出现;第三个模块儿是进行排序输出等,将最终出现次数最多的十个词显示出来。

具体细节:定义一个结构体word,包含三个变量:字符串str,来记录分离出来的单词;整型数number,用来记录该单词出现的次数;float型变量frequency,用来记录该单词在文章中出现的频率。因为考虑到一篇英文文章常用的单词为1000左右,所以我声明了一个长度为1000的结构体word类型的数组W[1000],用来存放从文件中读入的单词。

程序流程:从文件中读入字符判断是否为字母,如果是则继续读入,直到读入的字符不是字母位止,从而形成一个单词。将这个单词送去和W[1000]中已有的单词来进行比较,如果已存在该单词,就在单词的number上加1,如果不存在,则将该单词存入W[1000]中。最后分析排序,输出结果。

程序结果:

#include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
#include<time.h>
struct word            //声明单词结构体
{
    char str[20];             //单词
    int number;               //出现次数   
    float frequency;          //出现频率  
}W[1000];

int sum;
double all=0;

void Deal(char s[])       //处理字符串
{
    int i,j;
    int t;
    int flag=0;  //flag为零时说明没有匹配

       for(i=0;i<=sum;i++)
    {
        if(strcmp(W[i].str,s)==0)
        {
             W[i].number++;
             flag=1;
           }
        
    }
    if(flag==0)
    {
        for(j=0;j<20;j++)
          W[sum].str[j]=s[j];
        W[sum].number++;
        sum++;
    }
      
}

void Read()      //读文件函数
{
    double start,finish;
    start=(double)clock();

    int i,j;
    char ch,s[20];
    FILE*fp;                                      //打开文件开始读入字符
    if((fp=fopen("三个火枪手(英文版).txt","r"))==NULL)
    {
        printf("无法打开此文件\n");
        exit(0);
    }

    for(i=0;i<999;i++)  //单词的出现的次数置零
        W[i].number=0;
    sum=0;    //sum置零
    ch=NULL;   //ch置空

    while(ch!=-1)      //不到文件结尾就继续循环读入字符
    {
        for(i=0;i<20;i++)  // s[]置零
            s[i]='\0';

         ch=fgetc(fp);  //读入字符
        if(isalpha(ch)!=0)  //判断ch是否为字母
        {
            for(i=0;;i++)    
            {
                s[i]=ch;
                ch=fgetc(fp);
                if(isalpha(ch)!=0)continue;
                else {break;}
            }

            for(i=0;i<20;i++)         //转换成全小写
            {
                if(s[i]>=65 && s[i]<=90)
                    s[i]=s[i]+32;
            }
            Deal(s);
        }
        else {continue;}
    }

    finish=(double)clock();
    printf("读取时间:%.4fms\n",(finish-start));
}

void jisuan()   //计算每个单词出现的频率和总单词数
{
    double start,finish;
    start=(double)clock();

    for(int i=0;i<1000;i++)
    {
        W[i].frequency=W[i].number/all;
        if(W[i].number>0)all=all+W[i].number;
    }

    finish=(double)clock();
    printf("计算时间:%.4fms\n",(finish-start));
}

void paixu()
{   
        double start,finish;
    start=(double)clock();

    word t;
    for(int j=0;j<999;j++)
        for(int i=0;i<999-j;i++)
            if(W[i].number<W[i+1].number)
            {
                t=W[i];W[i]=W[i+1];W[i+1]=t;
            }
    finish=(double)clock();
    printf("排序时间:%.4fms\n",(finish-start));
}

int main(int argc, char* argv[])
{
    int i;
    double start,finish;

    start=(double)clock();
    Read();
    jisuan();
    paixu();
    
    printf("数据来源: 《三个火枪手》\n");
    printf("单词      出现次数\n");
    for(i=0;i<10;i++)
        printf("%-8s  %8d\n",W[i].str,W[i].number) ;
    
    printf("总单词种类:  %.0lf\n",all);

    finish=(double)clock();
    printf("总运行时间:%.4fms\n",(finish-start));
    return 0;
}