• 分析一个文本文件(英文文章)中各个词出现的频率,并且把频率最高的10个词打印出来


      第一次这样交作业,好不习惯,废话不多说,上代码及整个分析编写过程。
      这次的程序大约花费了不到4个小时(2课时+一晚上),整体的设计思想是分三部分:从文件读入并分析收集单词,统计单词的频率,排序输出。下面是具体实现过程:
    1.   建立一个哈希表结构体Hash_table和一个单词缓存区buffer并分别对其做初始化
      typedef struct Hash{ 
          int count; 
          char str[20];     
      }Hash_table;
     初始化:
    void initial_buffer ()
    {
        for (tail_prob = 0; tail_prob < MAXWORD ;tail_prob++)
        {
            buffer[tail_prob++] = '';
        }
        tail_prob = 0;
    }
    
    void initial_hashtable ()
    {while (i < hashnum)
        {
            hash_table[i].count = 0;
            i++;
        }
    }
      
    2. 统计文件中单词出现的频率,将单词及其频率存储在哈希表中

      

    void find_frquence(FILE *in,FILE *out)
    {do
        {
            if (character >0x20 && character < 0x80)
            {
                if (flag==1)
                {
                    copytobuffer (character);
                }
                else //新单词,且是字母和数字的组合*/ 
                {
                    if(find_match())
             { }
              else { addtoHash (); Hcount++; } copytobuffer (character); flag = !flag; } } else { if (character <= 0x20 || character >= 0x80) { if (flag) { buffer[tail_prob] = '/0'; if (find_match) /*如果能够找到,则对应的频率加1,find_match实现频率加1*/ { } else /*不能找到,则到哈希表中*/ { addtoHash (); Hcount++; } copytobuffer (character); flag = !flag; } else { copytobuffer (character); } } } }while ((character = fgetc (in)) != EOF); /*处理最后缓冲区所存储的单词*/ if(find_match()) { } else { addtoHash(); Hcount++; } }

     3.使用除留余数法查询哈希表中的单词,若存在则频率+1

    int find_match ()
    {while (hash_table[index].count)
        {
            if (len1 == len2)     //些比较len1和len2是否相等,如果不等再比较
            {
                for (i = 0;i<len1 && *str == *temp;i++)
                {
                    str++;
                    temp++;
                }
                if (i != len2)
                {
                    index = (index + 1) % hashnum;
                    temp = hash_table[index].str;
                    str = buffer;
                    return -1;
                }
                else   //能找到
                {
                    hash_table[index].count++;
                    return TURE;
                }
            }
            else
            {
                index = (index + 1) % hashnum;
                temp = hash_table[index].str;
                str = buffer;
                return -1;
            }
        }
    }

    4.排序后输出到一个文件中,也可输出在屏幕上

    void Hash_sort(FILE *out)
    {
        while (i < Hcount)  
        {
            /*找到第一个遇见的频率非零的结点*/
            while (hash_table[index].count == 0)
            {
                index ++;
            }
            symbol = hash_table[index].count;  /*充当最大值*/
            num = index;
            index++;
            while (index < hashnum)
            {
                if (symbol < hash_table[index].count && hash_table[index].count)
                {
                    symbol = hash_table[index].count;
                    num = index;
                }
                index ++;
            }
            len = strlen (hash_table[num].str);
            //printf("%d	",hash_table[num].count);
            //printf("%s
    ",hash_table[num].str);
            fprintf(out,"%s,%d
    ",hash_table[num].str,hash_table[num].count);
            hash_table[num].count = 0;
            i++;
            index = 0;
        }  
    }

    5.源代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define  FOOL     int
    #define  TURE      1
    #define  FALSE     0
    #define  MAXWORD   20
    #define  hashnum  1024
    
    /*采用哈希表结点结构*/
    typedef struct Hash{ 
        int count; 
        char str[20];     /*不一定为1,而是动态分配*/
    }Hash_table;
    
    Hash_table hash_table[hashnum];
    
    char buffer[256];     /*缓冲区大小,用来暂时存储单词*/
    int tail_prob;              /*缓冲区结束位指针 */
    int Hcount = 0;                   /*用来计算有多少单词*/
    
    /******************************************************************/
    /**                      初始化操作                              **/
    /**                                                              **/
    void initial_buffer ()
    {
        for (tail_prob = 0; tail_prob < MAXWORD ;tail_prob++)
        {
            buffer[tail_prob++] = '';
        }
        tail_prob = 0;
    }
    
    void initial_hashtable ()
    {
        unsigned int i;
        i = 0; 
        while (i < hashnum)
        {
            hash_table[i].count = 0;
            i++;
        }
    }
    /******************************************************************/  
    /**    关于缓冲区的操作                                          **/ 
    /**                                                              **/
    
    /*把一个字符拷贝到缓存区中*/
    void copytobuffer (char character)
    {    
        if (tail_prob >= MAXWORD)
        {
            printf("Usag:this word is too long!");
            exit (-1);
        }
        buffer[tail_prob++] = character;
    }
    
    /*清除缓冲区*/
    void clear_buffer ()
    {
        while (tail_prob != 0)
        {
            buffer[--tail_prob] = '';
        }
    }
    
    /**************************************************************/
    /** 找哈希表的关键字,这里使用的是把字符串的值相加再求与哈希表**/
    /**长度的余                                                  **/  
    unsigned int get_key (char *str)
    {
        unsigned result = 0;
        do
        {
            result = result + (*str);
            str++;
        }while (*str != NULL);
        result = result % hashnum;
        return result;
    }
    
    /***************************************************************/
    /**看哈希表中是否有对应的单词,有返回真                       **/
    /**                                                           **/
    int find_match ()
    {
        int i;
        char *str;
        char *temp;
        int len1;          /*缓冲区中单词的长度*/
        int len2;          /*哈希表中单词的长度*/
        int index;
    
        str = buffer;
        index = get_key (buffer);
        temp = hash_table[index].str;
        len1 = strlen (buffer);
        len2 = strlen (temp);
    
        while (hash_table[index].count)
        {
            if (len1 == len2)     /*些比较len1和len2是否相等,如果不等再比较*/
            {
                for (i = 0;i<len1 && *str == *temp;i++)
                {
                    str++;
                    temp++;
                }
                if (i != len2)
                {
                    index = (index + 1) % hashnum;
                    temp = hash_table[index].str;
                    str = buffer;
                    return -1;
                }
                else   //能找到
                {
                    hash_table[index].count++;
                    return TURE;
                }
            }
            else
            {
                index = (index + 1) % hashnum;
                temp = hash_table[index].str;
                str = buffer;
                return -1;
            }
        }
    }
    
    /***************************************************************/
    /** 根据缓冲区里面的字符生成哈希表                            **/
    /**                                                           **/
    void addtoHash()
    {
        char str_temp[256];
        char *str;
        char *temp;
        int len;
        unsigned int index;
        int i;
    
        i=0;
        str = str_temp;
        strcpy (str,buffer);
        index = get_key (str);
        len = strlen(str);
        temp = hash_table[index].str;
    
        while (hash_table[index].count)  /*找到没有被储存的结点*/
        {
            index = (index + 1) % hashnum;
        }
        hash_table[index].count++;
        while (i < len)  /*复制字符串*/
        {
            *temp++ = *str++;
            i++;
        }
    }
    
    /***************************************************************/
    /**                 排序后输出到out文件中                     **/
    /**                                                           **/
    void Hash_sort(FILE *out)
    {
        int index;
        unsigned int symbol; /*最大值*/
        int num;
        int len;
        int i = 0;
        index = 0;
        /*排序输出到out文件中,共有Hcount个单词*/ 
        while (i < Hcount)  
        {
            /*找到第一个遇见的频率非零的结点*/
            while (hash_table[index].count == 0)
            {
                index ++;
            }
            symbol = hash_table[index].count;  /*充当最大值*/
            num = index;
            index++;
            while (index < hashnum)
            {
                if (symbol < hash_table[index].count && hash_table[index].count)
                {
                    symbol = hash_table[index].count;
                    num = index;
                }
                index ++;
            }
            len = strlen (hash_table[num].str);
            //printf("%d	",hash_table[num].count);
            //printf("%s
    ",hash_table[num].str);
            fprintf(out,"%s,%d
    ",hash_table[num].str,hash_table[num].count);
            hash_table[num].count = 0;
            i++;
            index = 0;
        }  
    }
    
    
    /*****************************************************************
    /*找文件in中单词出现的频率,存储其单词以及其频率,调用find_match*/
    /*输入的字符小于等于Ox20或者大于0x80时说明不是数字或者字母。但是*/
    /*也能组成一个单词                                              */
    void find_frquence(FILE *in,FILE *out)
    {
        char character;
        FOOL flag;
        flag = 1; /*开关语句*/
        initial_buffer();
        initial_hashtable ();
        /*当没有到文件结束时*/
        character = fgetc (in);
        do
        {
            if (character >0x20 && character < 0x80)
            {
                if (flag)
                {
                    copytobuffer (character);
                    //find_match();
                }
                else /*新单词,且是字母和数字的组合*/ 
                {
                    buffer[tail_prob] = '';/*表示结束*/
                    if(find_match ())  /*如果能够找到,相对应的频率加1*/
                    {
                        //Tprob->count++;
                    }
                    else             /*不能找到,则生成一个新的结点加入孩子兄弟链表中*/
                    {
                        addtoHash ();
                        Hcount++;
                    }
                    clear_buffer ();   
                    copytobuffer (character);
                    flag = !flag;
                }
            }
            else
            {
                if (character <= 0x20 || character >= 0x80)
                {
                    if (flag)
                    {
                        buffer[tail_prob] = '/0';
                        if (find_match ())   /*如果能够找到,则对应的频率加1,find_match实现频率加1*/
                        {
                            //      Tprob->count++;
                        }
                        else                 /*不能找到,则到哈希表中*/
                        {
                            addtoHash ();
                            Hcount++;
                        }
                        clear_buffer ();   /*清除缓冲区*/
                        copytobuffer (character);
                        flag = !flag;
                    }
                    else
                    {
                        copytobuffer (character);
                    }
                }
            }// if - else 结束 
        }while ((character = fgetc (in)) != EOF);
    
        /*处理最后缓冲区所存储的单词*/
        if(find_match())
        {
            //  Tprob->count++;
        }
        else
        {
            addtoHash();
            Hcount++;
        }
    
        /*排序并按从小到大输出到out文件中*/
        Hash_sort(out);
    }
    
    
    /**************************************************************/
    
    void main(int argc,char *argv[])
    {
        FILE *in;
        FILE *out;
        char temp_string1[256];
        char temp_string2[256];
        if((in=fopen("temp_string1.txt","r"))==NULL)
        {  
            printf("Please input the file you want to compile:
    ");    
            exit(0);
        }
        in=fopen("temp_string1.txt","r");
    
        //in = fopen (temp_string1,"r");
        out = fopen ("temp_string2.txt","w");
    
        /*找到各个单词,并且存储其频率,按频率顺序排列后输出到out中*/
        find_frquence (in,out);
       fclose(in); fclose(out);
    }

    6.总结

      说实话,自己学的真的很渣,在有了大体思想后就开始从网上各种收集资料,但在编写的过程中还是遇到了很多问题,编译各种不通过,最后在多处求教同学和查资料后,得到了解决。这次的作业体会最深的一点就是,什么事都得靠自己去完成(因为不能类同了)!在这次的作业中,也对fgetc有了很深的了解,同时了解到了字符在16进制中的表示,还有一点就是,对哈希表又重新温习了一次。继续努力学习,望鼓励支持,哈哈

  • 相关阅读:
    集合关系运算 交、差、并集
    字符串 数字 列表 元祖 字典 的不同分类and集合的概念
    我的python之路6(基础练习)
    我的python之路6(整理)
    编写Linux下socket协议TCP和UDP的Client Server程序
    linux添加新用户
    HTML5怎样在网页中使用摄像头功能 时间:2013-04-10 19:56 来源:18素材
    boost 同步定时器
    C++的multiple definition of *** first defined here错误
    TCP与UDP的区别,以及它们各自的定义
  • 原文地址:https://www.cnblogs.com/caojinfeng/p/3579293.html
Copyright © 2020-2023  润新知