【C语言】中文文本文件之词频统计

【C语言】中文文本文件之词频统计

一、前言

          以下代码都是针对于小文本文件,不适用于大文本文件

二、 代码实现一

2.1 源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Word //声明一个结构体,分别存储单词和对应单词的个数
{
    size_t time;
    char word[230000];
};


void Copy(struct Word *array, FILE *read, const int length);
void Count_for_word(struct Word *array, const int length);

// 函数一
void Copy(struct Word *array, FILE *read, const int length) //该函数的作用是把文本中的单词复制到数组中
{

    char ch, word[230000];
    int i = 0, j;

    while (fscanf(read, "%s", &word) != EOF)
    {
        strcpy(array[i].word, word); // 将word复制到arra[i]中
        ++i;                         //移动数组的下标
    }
    fclose(read);                  // 关闭文件指针
    Count_for_word(array, length); // 调用自定义函数
}

// 函数二
void Count_for_word(struct Word *array, const int length) //统计单词的个数
{
    int i, j;

    for (i = 0; i < length; i++)
    {
        array[i].time = 1;
        for (j = i + 1; j < length; j++)
        {
            if (strcmp(array[i].word, array[j].word) == 0)
            {
                ++array[i].time;            //如果遇到相同的单词,就把相应的结构体部分增加 1
                strcpy(array[j].word, " "); //并把该单词置为空,因为已经读取到数组中了,所以这里改变的是数组的数据,不影响文本数据
            }
        }
    }
    
    printf("the file have %d word\n\n", length);
    
    for (int index = 0; index < length; index++) // 冒泡排序
    {
        for (int temp = 0; temp < length - index-1; temp++)
        {
            // 例如:length = 5
            if (array[temp].time < array[temp + 1].time)
            {
                struct Word word = array[temp];
                array[temp] = array[temp + 1];
                array[temp + 1] = word;
            }
        }
    }


    for (i = 0; i < length; i++)
        if (strcmp(array[i].word, " ") != 0)
        { // 当不相等时候
            //printf("%-5s occurrs  %-3d %s\n", array[i].word, array[i].time, ((array[i].time > 1) ? "times" : "time"));
            printf("%-5s:%-3d\n", array[i].word, array[i].time);
        }
}

int main(int argc, char *argv[])
{
    char word[230000];
    int length = 0, ch;
    FILE *read;
    struct Word *array;

    if (argc < 2 || argc > 2)
    {
        printf("usage: %s filename\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    // 打开文本
    if ((read = fopen(argv[1], "r")) == NULL)
    {
        printf("open file failure\n");
        exit(EXIT_FAILURE);
    }
    //
    while (fscanf(read, "%s", &word) != EOF) //测试是否读到文件末尾
    {
        ++length; //统计文本中单词的个数
    }

    rewind(read);                                 //把文件指针置为文本开始的位置,并清除错位信息
    array = malloc(sizeof(struct Word) * length); // 单词的长度动态分配内存
    Copy(array, read, length);                    // 调用自定义函数

    return 0;
}

2.2 执行结果

在这里插入图片描述

三、代码实现二

3.1 源码
#include <stdio.h>
#include <string.h>

struct words //单词结构体
{
    char word[115];
    int count;
};

void quick_sort(char s[], int l, int r)
{
    if (l < r)
    {
        int i = l, j = r, x = s[l];
        while (i < j)
        {
            while (i < j && s[j] >= x) //从右到左找到第一个小于x的数
                j--;
            if (i < j)
                s[i++] = s[j];

            while (i < j && s[i] <= x) //从左往右找到第一个大于x的数
                i++;
            if (i < j)
                s[j--] = s[i];
        }

        s[i] = x;                //i = j的时候,将x填入中间位置
        quick_sort(s, l, i - 1); //递归调用
        quick_sort(s, i + 1, r);
    }
}


int main(int argc, char *argv[])
{
    struct words word[12000] = {0}, stmp = {0};
    int i = 0, j = 0, k = 0, flag = 0;
    int wors = 0;
    char c;
    char tmp[100] = {0}; // 存储每个词语,最多存储50个字
    FILE *fp = NULL;

    fp = fopen(argv[1], "r");
    if (fp == NULL)
    {
        printf("文本打开错误");
        return -1;
    }

    //读文件解析词语
    while ((c = fgetc(fp)) != EOF) // 按字符读取
    {
        //以换行符作为单词标识符。
        if (c != '\n')
        {
            tmp[j++] = c; // 在未遇到词语标识符之前将
            //printf("%s\n",tmp);
        }
        else
        {
            tmp[j] = '\0'; // 清零操作
            j = 0;         // 重置
            flag = 0;

            //判断单词是否已经记录 如果已有则使用率加1
            for (k = 0; k < i; k++)
            {
                if (strcmp(tmp, word[k].word) == 0) // 判断相等函数
                {
                    word[k].count++; // 统计相同的词语的个数
                    flag = 1;        // 设置标识符为1
                    break;
                }
            }
            //没有则存入单词结构体数组保存
            if (!flag)
            {
                strcpy(word[i].word, tmp);
                word[i].count++;
                i++;
            }
             memset(tmp, 0, sizeof(tmp));
            memset(tmp, '\0', sizeof(tmp));
        }
    }

    fclose(fp);

 
    
    int length = sizeof(tmp) / sizeof(char); //求数组的长度
    quick_sort(tmp, 0, length);
    for (int kk = 0; kk < length; kk++)
    {
        printf("[%s][%d]\n", word[kk].word, word[kk].count);
    }

    // 输出排序后的所有已记录单词
   
    /* for (k = 0; k < i; k++)
    {
        // printf("[%s][%d]\n", word[k].word, word[k].count);
        printf("[%s]\n", word[k].word);
    } */

    return 0;
}

3.2 执行结果

在这里插入图片描述

  • 7
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贾继康

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值