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语言实现英文文本词频统计 的全部内容, 来源链接: utcz.com/p/244980.html

回到顶部