C語言實現(xiàn)英文文本詞頻統(tǒng)計
這幾天寫了一個基于C語言對文本詞頻進行統(tǒng)計的程序,開發(fā)及調(diào)試環(huán)境:mac集成開發(fā)環(huán)境Xcode;測試文本,馬丁.路德金的《I have a dream》原文演講稿。
主要運行步驟:
1. 打開文本把文本內(nèi)容讀入流中并且開辟相應(yīng)空間放入內(nèi)存
2 .對文本內(nèi)容進行處理,去除大寫字母(轉(zhuǎn)化為小寫),去除特殊字符
3. 基于單鏈表對詞頻進行統(tǒng)計
4. 把統(tǒng)計結(jié)果進行歸并排序
5.打印輸出全部詞頻或者頻率最高的10個單詞和其出現(xiàn)次數(shù)
6.釋放所有結(jié)點消耗的內(nèi)存
廢話不多說,上代碼!
//
// main.c
// word_frequency_statistic
//
// Created by tianling on 14-3-16.
// Copyright (c) 2014年 tianling. All rights reserved.
// 實現(xiàn)英文文本的詞頻統(tǒng)計
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ERROR 1
#define OK 0
const int WORD_LENGTH = 250;//定義單個單詞最大長度
typedef int status;
/*
**定義存儲單詞及其出現(xiàn)次數(shù)的結(jié)構(gòu)體
*/
typedef struct Node{
char word[WORD_LENGTH];
int time;
struct Node *next;
}wordNode;
wordNode *headNode = NULL;//定義鏈表頭指針
/*
**函數(shù)聲明
*/
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];//定義用以臨時存放單詞的數(shù)組
FILE *file;
int count,articleWordNum = 0;//定義統(tǒng)計結(jié)點個數(shù)的變量
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);//關(guān)閉文件
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;
}
/*
**查找單詞所在結(jié)點
*/
wordNode *wordSearch(char *word,int *num){
wordNode *node;//聲明一個新結(jié)點
if(headNode == NULL){//若頭結(jié)點為空
node = (wordNode*)malloc(sizeof(wordNode));
strcpy(node->word, word);//將第一個單詞賦值給這個新結(jié)點
node->time = 0;//初始化該單詞的出現(xiàn)次數(shù)
*num+=1;
headNode = node;//將頭結(jié)點指向這個新結(jié)點
return node;
}
wordNode *nextNode = headNode;
wordNode *preNode = NULL;
while(nextNode != NULL && strcmp(nextNode->word, word) != 0){
preNode = nextNode;
nextNode = nextNode->next;
}
//若該單詞不存在,則在鏈表中生成新結(jié)點
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;
}
/*
**詞頻統(tǒng)計
*/
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("該文件無內(nèi)容!");
}else{
wordNode *preNode = headNode;
printf("總詞量 %d \n",*num);
while(preNode != NULL){
printf("%s 出現(xiàn)次數(shù) %d\n",preNode->word,preNode->time);
preNode = preNode->next;
}
}
}
/*
**打印詞頻最高的10個詞
*/
void PrintFirstTenTimes(){
if(headNode == NULL){
printf("該文件無內(nèi)容!");
}else{
wordNode *preNode = headNode;
int i = 0;
printf("出現(xiàn)次數(shù)最多的10個詞如下: \n");
while (preNode != NULL && i<=10) {
printf("%s 出現(xiàn)次數(shù) %d\n",preNode->word,preNode->time);
preNode = preNode->next;
i++;
}
}
}
/*
**對詞頻統(tǒng)計結(jié)果進行歸并排序
*/
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;
}
}
/*
**根據(jù)排序結(jié)果更換頭結(jié)點
*/
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++){
//篩選并將字符串中的大寫字母轉(zhuǎn)化為小寫字母
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++;
}
}
}
}
}
/*
**釋放所有結(jié)點內(nèi)存
*/
void release(){
if(headNode == NULL)
return;
wordNode *pre = headNode;
while(pre != NULL){
headNode = pre->next;
free(pre);
pre = headNode;
}
}
調(diào)試結(jié)果:(Xcode環(huán)境)

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
詳解如何在code block創(chuàng)建一個C語言的項目
這篇文章主要介紹了詳解如何在code block創(chuàng)建一個C語言的項目,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
Qt實現(xiàn)SqlRelationalTable關(guān)聯(lián)表組件
在Qt中我們可以通過拖拽的方式將不同組件放到指定的位置,實現(xiàn)圖形化開發(fā)極大的方便了開發(fā)效率,本章將重點介紹SqlRelationalTable關(guān)聯(lián)表組件的常用方法及靈活運用,感興趣的可以了解一下2023-12-12
可能是全網(wǎng)最詳細的Qt連接MySQL數(shù)據(jù)庫教程
QT眾所周知是一個開源的,以C++為底層的可視化工具庫,下面這篇文章主要給大家介紹了關(guān)于最詳細的Qt連接MySQL數(shù)據(jù)庫教程的相關(guān)資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下2023-04-04

