深白一.单词排序

题目描述

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

严格定义如下:

:= 定义

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值