• 深白一.单词排序


    题目描述

    某文本文件由"字符"组成,"字符"被"分割符"分割为"单词"。
    要求程序接受指定文件,分析出其有哪些"单词"组成,并统计每一个"单词"的出现次数,
    最后根据出现次数由少到多排序,输出"单词"列表。

    严格定义如下:

    := 定义

    <文件> := <元素> 的0次或多次重复
    <元素> :=  { <分割符> | <单词>}
    <分割符> := <分割字符> 的1次或多次重复
    <分割字符> :={ 空格符 | TAB符 | 回车符 | 换行符}
    <单词> := { 非<分割字符>的字符} 的1次或多次重复

    程序输入格式:
    在命令提示符下
     程序名  <指定的文件>

    程序输出格式:
    输出到标准输出:
    <出现次数最少的单词>  <其出现次数>
    <出现次数次少的单词>  <其出现次数>
    。。。
    <出现次数最多的单词>  <其出现次数>

    补充要求:
    程序能处理的文件大小,单词大小,仅受计算机内存和硬盘空间的限制。
    任何情况下,不能出现崩溃,不正常退出,内存泄漏,令用户感觉莫名其妙的结果。

    例:
    ------文件内容开始-----
      aa bbb aa
    ------文件内容结束-----

    输出结果:
    bbb 1
    aa 2


    * 只能用C。”strtok()”不能用。排序使用库函数”qsort”。

    程序代码:

    /*************************************************************************************
     *FILE:Count_Sort.cpp
     *DESCRIPTION:统计文本文件中各单词出现次数,并按照次数的升序排序
     *REFERENCE:none
     *MODIFIED:none
     *MADE BY:Micro Philosopher, 2012-11-05  
     ************************************************************************************
    */

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include "Count_Sort.h"
        
    /***********************************************************
    **************************主程序****************************
    ***********************************************************
    */

    void main()
    {
        char programname[NAME_LENTH],filename[NAME_LENTH];
        char program[]="main.cpp",file[]="in.txt";

    INPUT:
        printf("Please input program name and file name.\n");
        scanf("%s%s",programname,filename);
        printf("\n");
        
        if(!(strcmp(programname,program) || strcmp(filename,file)))  //程序名和文件名输入正确才能进行
        {
            FILE *fp;
            if((fp = fopen("in.txt","r"))==NULL)
            {
                printf("cannot open this file\n");
                exit(0);
            }
            Fun(fp);
            fclose(fp);
        }
        else
        {
            printf("No such program or file!\n");
            goto INPUT;                                              //返回重新选择
        }
    }

    /***********************************************************
    *****该函数将实现文本的读入,单词的统计排序以及文本输出*****
    ***********************************************************
    */

    int Fun(FILE *in)
    {
        int flag_FormerIsLetter = 0;     //标志量,初始值置为0,当yes==0时,代表前一个字符不是字母。
        char ch;                         //用于读取文件中的一个字符数据
        char *str;                       //用于暂存单词的字符数据
        char *tmp;                       //用于对*word进行内存分配
        int order = 0;                   //单词的第几位
        int file_len;                    //文件长度

        struct Word *head = NULL;
        struct Word *p;
        struct Word *temp;
        
        fseek(in,0,SEEK_END);             //将文件指针移到文件结尾      fseek(文件类型指针,位移量,起始点)
        file_len = ftell(in);             //取得文件总长度              ftell:取得相对于文件开头的位移量
        rewind(in);                         //将文件指针移到文件头
        
        str = new char[file_len];        //建立用于存放一个单词的动态数组
        
        while (!feof(in))                //feof():检测EOF文件结束标志
        {
            memset(str, 0, file_len);    //memset():清零操作
            
            /**************************单词输入*************************/
            while (!feof(in))
            {
                ch = fgetc(in);                                              //读一个字符到ch中
                
                if((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))     //如果是字母
                {            
                    str[order++] = ch;
                    flag_FormerIsLetter = 1;
                }
                else                                                         //如果不是字母
                {
                    if (flag_FormerIsLetter != 0)                            //代表一个单词的结束
                    {                
                        order = 0;                                           //单词位置清零
                        flag_FormerIsLetter = 0;                             //标志位清零
                        break;
                    }
                }
            }
            
            /**************************出现次数统计*************************/
            if (strlen(str) >= 1)                                     //有单词出现           strlen:字符串的实际长度,不算'\0'
            {
                temp = head;                                          //从头开始,依次比较
                while (temp != NULL)
                {
                    if (!(strcmp(temp->words, str)))                  //如果跟已存在的单词一样,则count加1   strcmp:两个参数相等
                    {
                        temp->count++;
                        break;
                    }
                    temp = temp->next;
                }
                if (temp == NULL)                                     //如果不一样,则插入链表中。
                {
                    p = (struct Word*)malloc(sizeof(struct Word));
                    p->next = head;
                    head = p;
                    
                    tmp = (char *)malloc(file_len);
                    p->words = tmp;
                    
                    memset(p->words, 0, file_len);
                    strcpy(p->words, str);
                    p->count = 1;
                }
            }
        }
        
        /**************************冒泡排序*************************/
        sort(head,file_len);
        
        /**************************输出*************************/
        while (head != NULL)
        {
            printf("%-20s%d\n",head->words,head->count);
            head = head->next;
        }

        return 0;
    }

    /***********************************************************
    ****对链表中的单词按出现次数进行升序排序,采用冒泡排序法****
    ***********************************************************
    */

    void sort(struct Word *head,int length)
    {
        char *str;
        str = new char[length];
        int n;
        struct Word *p;
        struct Word *p2;
        for (p = head;p != NULL;p = p->next)
        {
            for (p2 = p;p2 != NULL;p2 = p2->next)
            {
                while (p2->count < p->count)               //大的往下,小的往上
                {
                    strcpy(str, p->words);
                    n = p->count;
                    strcpy(p->words, p2->words);
                    p->count = p2->count;
                    strcpy(p2->words, str);
                    p2->count = n;
                }
            }
        }
    }
    /*************************************************************************************
     *FILE:Count_Sort.h
     *DESCRIPTION:头文件,类的定义,函数的声明
     *REFERENCE:none
     *MODIFIED:none
     *MADE BY:Micro Philosopher, 2012-11-05  
     ************************************************************************************
    */
    #define NAME_LENTH 32
     
    struct Word
    {
        char *words;
        int count;
        struct Word *next;
    };


    int Fun(FILE *in);
    void sort(struct Word *head,int length);

    in.txt和结果:

  • 相关阅读:
    cocos2dx 3.x 集成protobuf
    Lua面向对象之三:其它一些尝试
    Lua面向对象之二:类继承
    Lua面向对象之一:简单例子
    cocos2dx lua 绑定之二:手动绑定自定义类中的函数
    向量点积、叉积的意义
    cocos2dx lua 绑定之一:自动绑定自定义类中的函数
    Lua和C++交互 学习记录之九:在Lua中以面向对象的方式使用C++注册的类
    Lua和C++交互 学习记录之八:C++类注册为Lua模块
    Lua和C++交互 学习记录之七:C++全局函数注册为Lua模块
  • 原文地址:https://www.cnblogs.com/zss/p/3200535.html
Copyright © 2020-2023  润新知