C语言实现英文文本词频统计
作者:-天凌-
这篇文章主要为大家详细介绍了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环境)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。