深白一.单词排序

题目描述

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

严格定义如下:

:= 定义

<文件> := <元素> 的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和结果:

原文地址:https://www.cnblogs.com/zss/p/3200535.html