统计文本文档中单词的个数,并输出出现频率最高的10个单词和次数

      在看到这个题目后,首先确定了我的编程语言,我决定用C语言编写。因为C语言中有很多关于字符串操作的函数,做起来会比较简单。然后创建结构体存放单词和单词数量,因为单词和单词数量要一一对应,所以采用了结构体。将单词存放于结构体指针的链表中。然后就是进行排序,选出10个出现次数最高的单词,并记录对应的次数。然后我整理下解题的思路:

                          1.打开文件,统计每个单词的数量

                          2.对单词对应的次数进行排序,然后输出。

下面就是2个模块和源代码:

while(!feof(fp))    //统计文本文档中每个单词的数量。存放于链表中
        {
             char *p=(char*)malloc(20*sizeof(char));
             fscanf(fp,"%s",p);
              if(Head==NULL)
              {
                   struct word *temp=(struct word*)malloc(sizeof(struct word));
                   strcpy(temp->w,p);
                   temp->k=1;
                   temp->next=NULL;
                   Head=temp;
              } 
              else 
              {
                   struct word *pp=Head;
                   while(pp!=NULL) 
                   {
                       if(strcmp(pp->w,p)==0)
                       {
                            int count = pp->k;
                            count++;
                            pp->k = count;
                            break;
                       }
                       pp=pp->next;
                   }
                   
                     if(pp==NULL)
                       {
                        struct word *temp = (struct word*)malloc(sizeof(struct word));
                        strcpy(temp->w, p);
                        temp->k=1;
                        temp->next=Head;
                        Head=temp;
                       }
              }
        }

统计文本文档中每个单词的数量,在每次从文档中读取一个字符串后,假如这个单词没有出现过,就在对应的单词数置1,假如出现过,则对应的单词数+1.最后单词全部存放在了结构体指针的链表中,且和次数保持着对应关系。

for(i=0;i<10;i++)       //排序得出次数最大的十个单词,将单词和次数对应输出。
        {
            q=Head;
            while(q!=NULL)
            {
            if(q->k>a[i])    
            a[i]=q->k;
            else 
               q=q->next;
            }
           q=Head;
            while(q!=NULL)
            { 
                if(a[i]==q->k)
                {
                q->k=0;
                printf("次数:%d\t",a[i]);
                puts(q->w);
                break;
                }
                else q=q->next;
            }
        }

   

以上是排序模块。将统计后的单词用过次数进行排序,本来打算采用冒泡法,选出最大的十个,但是由于在每时每刻都要和单词数保持对应,我就放弃了冒泡法,而是每次都选出剩下的次数中最大的,然后将对应的单词做上标记,找出来后,将其对应的次数置0,是为了不影响下一次的排序。最后一共选出10个,将其输出即可。

下边是程序的源代码:

#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
struct word
{
    char w[20];
    int k;
    struct word *next;
};
int main()
{
    FILE *fp;
    int i;
    int a[10];
    struct word *Head=NULL;
    struct word *q;
    for(i=0;i<10;i++)
        a[i]=0;
    if((fp=fopen("wangdan.txt","r"))==NULL)
    {
        printf("无法打开此文件\n");
        exit(0);
    }
    while(!feof(fp))
        {
             char *p=(char*)malloc(20*sizeof(char));
             fscanf(fp,"%s",p);
              if(Head==NULL)
              {
                   struct word *temp=(struct word*)malloc(sizeof(struct word));
                   strcpy(temp->w,p);
                   temp->k=1;
                   temp->next=NULL;
                   Head=temp;
              } 
              else 
              {
                   struct word *pp=Head;
                   while(pp!=NULL) 
                   {
                       if(strcmp(pp->w,p)==0)
                       {
                            int count = pp->k;
                            count++;
                            pp->k = count;
                            break;
                       }
                       pp=pp->next;
                   }
                   
                     if(pp==NULL)
                       {
                        struct word *temp = (struct word*)malloc(sizeof(struct word));
                        strcpy(temp->w, p);
                        temp->k=1;
                        temp->next=Head;
                        Head=temp;
                       }
              }
        }
        for(i=0;i<10;i++)
        {
            q=Head;
            while(q!=NULL)
            {
            if(q->k>a[i])    
            a[i]=q->k;
            else 
               q=q->next;
            }
           q=Head;
            while(q!=NULL)
            { 
                if(a[i]==q->k)
                {
                q->k=0;
                printf("次数:%d\t",a[i]);
                puts(q->w);
                break;
                }
                else q=q->next;
            }
        }

      return 0;        
}

以上就是我整个写程序的思路。思路比较清晰,也比较易懂,就2个模块,一个统计单词个数,一个将统计的单词数进行排序。在排序的过程中,可能方法比较繁琐,不够简单,会比较浪费时间,所以有待改进。其实在用C语言编写程序的过程中,用结构体和指针解决问题会比较方便,但是呢又比较抽象,所以我们应该学会合适的运用。

原文地址:https://www.cnblogs.com/wangdan/p/3571642.html