C语言实现英文文本词频统计

 更新时间:2020年03月16日 10:28:20   作者:-天凌-  
这篇文章主要为大家详细介绍了C语言实现英文文本词频统计,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

这几天写了一个基于C语言对文本词频进行统计的程序,开发及调试环境:mac集成开发环境Xcode;测试文本,马丁.路德金的《I have a dream》原文演讲稿。

主要运行步骤:

1. 打开文本把文本内容读入流中并且开辟相应空间放入内存
2 .对文本内容进行处理,去除大写字母(转化为小写),去除特殊字符
3. 基于单链表对词频进行统计
4. 把统计结果进行归并排序
5.打印输出全部词频或者频率最高的10个单词和其出现次数
6.释放所有结点消耗的内存

废话不多说,上代码!

//
// main.c
// word_frequency_statistic
//
// Created by tianling on 14-3-16.
// Copyright (c) 2014年 tianling. All rights reserved.
// 实现英文文本的词频统计
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ERROR 1
#define OK 0
const int WORD_LENGTH = 250;//定义单个单词最大长度
typedef int status;


/*
 **定义存储单词及其出现次数的结构体
 */
typedef struct Node{
 char word[WORD_LENGTH];
 int time;
 struct Node *next;
}wordNode;

wordNode *headNode = NULL;//定义链表头指针

/*
 **函数声明
 */
wordNode *wordSearch(char *word,int *num);
status wordCount(char *word,int *num);
void printCountList(int *num);
void PrintFirstTenTimes();
void mergeSort(wordNode **head);
void FrontBackSplit(wordNode *head,wordNode **pre,wordNode **next);
void wordJob(char word[]);
wordNode *SortedMerge(wordNode *pre,wordNode *next);
void release();

status main(int argc,char *argv[])
{
 char temp[WORD_LENGTH];//定义用以临时存放单词的数组
 FILE *file;
 int count,articleWordNum = 0;//定义统计结点个数的变量
 int *num = &articleWordNum,choose;
 
 /*
  **读取文件
  */
 if((file = fopen("/Users/tianling/Documents/Data_Structure/word_frequency_statistic/word_frequency_statistic/article.txt", "r")) == NULL){
  //这里是绝对路径,基于XCode编译器查找方便的需求
  printf("文件读取失败!");
  exit(1);
 }
 
 while((fscanf(file,"%s",temp))!= EOF){
  wordJob(temp);
  count = wordCount(temp,num);
 }
 
 fclose(file);//关闭文件
 
 printCountList(num);
 
 printf("***********请选择***********\n");
 printf("*****1. 输出词频最高的10个词**\n");
 printf("*****2. 退出****************\n");
 
 scanf("%d",&choose);
 if(choose == 1){
  mergeSort(&headNode);
  PrintFirstTenTimes();

 }else{
  release();
  exit(0);
 }
 
 release();
 return 0;
 
 
}

/*
 **查找单词所在结点
 */
wordNode *wordSearch(char *word,int *num){
 wordNode *node;//声明一个新结点
 
 if(headNode == NULL){//若头结点为空
  node = (wordNode*)malloc(sizeof(wordNode));
  strcpy(node->word, word);//将第一个单词赋值给这个新结点
  node->time = 0;//初始化该单词的出现次数
  *num+=1;
  headNode = node;//将头结点指向这个新结点
  return node;
  
 }
 
 wordNode *nextNode = headNode;
 wordNode *preNode = NULL;
 
 while(nextNode != NULL && strcmp(nextNode->word, word) != 0){
  preNode = nextNode;
  nextNode = nextNode->next;
 }
 
 //若该单词不存在,则在链表中生成新结点
 if(nextNode == NULL){
  node = (wordNode*)malloc(sizeof(wordNode));
  strcpy(node->word, word);
  node->time = 0;
  node->next = headNode->next;
  headNode->next = node;
  *num+=1;
  
  return node;
 }else
  return nextNode;
 
}


/*
 **词频统计
 */
status wordCount(char *word,int *num){
 wordNode *tmpNode = NULL;
 tmpNode = wordSearch(word,num);
 
 if(tmpNode == NULL){
  return ERROR;
 }
 
 tmpNode->time++;
 
 return 0;
}


/*
 **打印所有词频
 */
void printCountList(int *num){
 if(headNode == NULL){
  printf("该文件无内容!");
  
 }else{
  wordNode *preNode = headNode;
  printf("总词量 %d \n",*num);
  
  while(preNode != NULL){
   printf("%s 出现次数 %d\n",preNode->word,preNode->time);
   preNode = preNode->next;
  }
 }
 
}


/*
 **打印词频最高的10个词
 */
void PrintFirstTenTimes(){
 if(headNode == NULL){
  printf("该文件无内容!");
  
 }else{
  wordNode *preNode = headNode;
  int i = 0;
  printf("出现次数最多的10个词如下: \n");
  
  while (preNode != NULL && i<=10) {
   printf("%s 出现次数 %d\n",preNode->word,preNode->time);
   preNode = preNode->next;
   i++;

  }
 }
}


/*
 **对词频统计结果进行归并排序
 */
void mergeSort(wordNode **headnode){
 wordNode *pre,*next,*head;
 head = *headnode;
 
 //若链表长度为0或1则停止排序
 if(head == NULL || head->next == NULL){
  return;
 }
 
 FrontBackSplit(head,&pre,&next);
 
 mergeSort(&pre);
 mergeSort(&next);
 
 *headnode = SortedMerge(pre,next);
 
}


/*
 **将链表进行分组
 */
void FrontBackSplit(wordNode *source,wordNode **pre,wordNode **next){
 wordNode *fast;
 wordNode *slow;
 
 if(source == NULL || source->next == NULL){
  *pre = source;
  *next = NULL;
 }else{
  slow = source;
  fast = source->next;
  
  while(fast != NULL){
   fast = fast->next;
   
   if(fast != NULL){
    slow = slow->next;
    fast = fast->next;
   }
  }
  *pre = source;
  *next = slow->next;
  slow->next = NULL;
 }
}


/*
 **根据排序结果更换头结点
 */
wordNode *SortedMerge(wordNode *pre,wordNode *next){
 wordNode *result = NULL;
 
 if(pre == NULL)
  return next;
 else if(next == NULL)
  return pre;
 
 if(pre->time >= next->time){
  result = pre;
  result->next = SortedMerge(pre->next,next);
  
 }else{
  result = next;
  result->next = SortedMerge(pre,next->next);
 }
 return result;
}


/*
 **处理大写字母及特殊字符
 */
void wordJob(char word[]){
 int i,k;
 char *specialChar = ",.;:'?!><+=|*&^%$#@\"";//定义特殊字符集
 
 for(i = 0;i<strlen(word);i++){
  //筛选并将字符串中的大写字母转化为小写字母
  if(word[i]>='A'&& word[i]<='Z'){
   word[i] += 32;
  }
  //筛选并去除字符串中的特殊字符
  for(k = 0;k<strlen(specialChar);k++){
   
   if(word[i] == specialChar[k]){
    
    while(i<strlen(word)){
     word[i] = word[i+1];
     i++;
    }
    
   }
  }
 }
 
}


/*
 **释放所有结点内存
 */
void release(){
 if(headNode == NULL)
  return;
 
 wordNode *pre = headNode;
 while(pre != NULL){
  headNode = pre->next;
  free(pre);
  pre = headNode;
  
 }
}

调试结果:(Xcode环境)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

您可能感兴趣的文章:

相关文章

  • C++调用matlab引擎实现三维图的绘制

    C++调用matlab引擎实现三维图的绘制

    这篇文章主要为大家详细介绍了C++如何调用matlab引擎实现三维图的绘制,文中的示例代码讲解详细,对我们学习C++和Matlab有一定的帮助,需要的可以参考一下
    2022-12-12
  • 如何将C++源程序改写为C语言

    如何将C++源程序改写为C语言

    C++中主要的与C的区别最大而且最常用的特性及修改方法,接下来我们一起来学习他们吧
    2021-08-08
  • C++ 数字的反转实现实例

    C++ 数字的反转实现实例

    这篇文章主要介绍了C++ 数字的反转实现实例的相关资料,需要的朋友可以参考下
    2017-06-06
  • C语言数据结构之 折半查找实例详解

    C语言数据结构之 折半查找实例详解

    这篇文章主要介绍了C语言数据结构之 折半查找实例详解的相关资料,需要的朋友可以参考下
    2017-06-06
  • 一文带你掌握C++中的继承

    一文带你掌握C++中的继承

    继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,本文详解介绍了C++中的继承,感兴趣的同学可以借鉴一下
    2023-05-05
  • c++使用正则表达式提取关键字的方法

    c++使用正则表达式提取关键字的方法

    这篇文章给大家介绍了c++使用正则表达式提取关键字的方法,相对来说比较简单,同时给大家提到了c++通过正则表达式提取匹配到的字符串的方法,非常不错,具有一定的参考借鉴价值,需要的朋友参考下吧
    2018-08-08
  • C++制作俄罗斯方块

    C++制作俄罗斯方块

    俄罗斯方块写过好几次了,每次的感觉都不一样,都有新的收获。就像达芬奇画鸡蛋一样,虽然都是画同样的鸡蛋,但是每次都有不同的收获。&nbsp;
    2016-05-05
  • QT利用QPdfWriter实现绘制PDF(支持表单输出)

    QT利用QPdfWriter实现绘制PDF(支持表单输出)

    这篇文章主要为大家详细介绍了QT如何利用QPdfWriter实现绘制PDF,并可以支持表单输出。文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2023-01-01
  • 详解C++实现匈牙利算法

    详解C++实现匈牙利算法

    匈牙利算法是一种在多项式时间内求解任务分配问题的组合优化算法,并推动了后来的原始对偶方法。美国数学家哈罗德·库恩于1955年提出该算法。此算法之所以被称作匈牙利算法,是因为算法很大一部分是基于以前匈牙利数学家Dénes K&#337;nig和Jen&#337; Egerváry的工作之上创建起来的
    2021-06-06
  • 一文带你掌握C语言中的文件操作

    一文带你掌握C语言中的文件操作

    文件通常是驻留在外部介质(如磁盘等)上的,在使用时才调入内存中来,本文主要来和大家介绍一下C语言中的文件操作,有需要的可以了解下
    2024-02-02

最新评论