词频统计更新

实现功能:从控制台输入文件路径,并统计单词总数及不重复的单词数,并输出所有单词词频,同时排序。

头文件

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

定义宏

#define WORD_LENGTH 250

定义结构体及全局变量

typedef struct Node
{
char word[WORD_LENGTH];
int time;
struct Node *next;
}wordNode; typedef struct TopNode
{
int sum; //全文单词个数
int num; //全文无重复单词个数
wordNode * next;
}TopNode; TopNode t; TopNode * L = NULL;

声明文件中使用的函数

wordNode *wordSearch(char *word);
void wordJob(char word[]);
void wordCount(char *word); void printCountList();
void PrintFirstTenTimes(); void mergeSort(wordNode **head);
void FrontBackSplit(wordNode *head,wordNode **pre,wordNode **next);
wordNode *SortedMerge(wordNode *pre,wordNode *next); void release();

主函数

int main(int argc,char *argv[])
{
char temp[WORD_LENGTH];//定义用以临时存放单词的数组
char file_path[];
wordNode * h;
FILE *file;
printf("请输入文件路径:");
gets(file_path);
if((file = fopen(file_path, "r")) == NULL)
{
printf("文件读取失败!");
exit();
}
L = &t;
L->num = ;
L->sum = ;
L->next = NULL;
while((fscanf(file,"%s",temp))!= EOF)
{
L->sum++;
wordJob(temp);
wordCount(temp);
}
fclose(file);
printCountList();
printf("\n\n输出词频最高的10个词\n");
h = L->next;
mergeSort(&h); //排序
PrintFirstTenTimes();
release();
return ;
}

查找单词所在节点并返回

wordNode *wordSearch(char *word)
{
char * t;
wordNode *node;
wordNode *nextNode = L->next;
if(L->next == NULL)
{
node = (wordNode*)malloc(sizeof(wordNode));
strcpy(node->word,word);
node->time = ;
node->next = NULL; //初试化,必须有,否则会发生错误。
L->num++;
L->next = node;
return node;
}
while(nextNode != NULL) //查找匹配单词
{
t = nextNode->word;
if(strcmp(t,word) == )
{
return nextNode;
}
nextNode = nextNode->next;
}
if(nextNode == NULL) //原链表中不存在该单词
{
node = (wordNode*)malloc(sizeof(wordNode));
strcpy(node->word, word);
node->time = ;
node->next = L->next;
L->next = node;
L->num++;
return node;
}
else
return nextNode; //返回查找到的节点
}

词频统计

void wordCount(char *word)
{
wordNode *tmpNode;
tmpNode = wordSearch(word); //word所在的节点
tmpNode->time++;
}

输出所有词频

void printCountList()
{
int i = ;
wordNode *node = L->next;
if(L->next == NULL)
{
printf("该文件无内容!"); }
else
{
printf("\n这篇文章总计%d词\n\n不重复单词共%d个\n",L->sum,L->num);
printf("\n输出所有单词的频数\n");
while(node != NULL)
{
printf(" %s:%d次\t",node->word,node->time);
i++;
node = node->next;
if(i% == )
printf("\n");
}
}
}

输出词频最高的10个词

void PrintFirstTenTimes()
{
wordNode *node = L->next;
int i = ;
if(L->next == NULL)
{
printf("该文件无内容!"); }
else
{
while (node != NULL && i<=)
{
printf("\t%s:%d次\n",node->word,node->time);
node = node->next;
i++;
}
}
}

对词频统计结果进行归并排序

void mergeSort(wordNode **headnode)
{
wordNode *pre,*next,*head;
head = *headnode;
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;
fast = source;
*next = slow->next; //pre和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;
for(i = ;i<strlen(word);i++)
{
if(word[i]>='A'&& word[i]<='Z')
{
word[i] += ;
continue;
}
if(word[i]<'a'||word[i]>'z')
{
if(i == (strlen(word)-))
{
word[i] = '\0';
}
else
{
k = i;
while(i < strlen(word))
{
word[i] = word[i+];
i++;
}
i = k;
}
}
}
}

释放所有结点内存

void release()
{
wordNode *pre;
if(L->next == NULL)
return;
pre = L->next;
while(pre != NULL)
{
L->next = pre->next;
free(pre);
pre = L->next;
}
}

ssh://git@git.coding.net:amberpass/cptjgx.git

https://git.coding.net/amberpass/cptjgx.git

最新文章

  1. Spring 02多种注入方式和注解实现DI
  2. js知识点
  3. js中ascii码的转换
  4. IOS 读取本地的Json/plist 文件
  5. android安全问题(八)伪造短信(利用原生android4.0漏洞)
  6. Mysql技术内幕-笔记-第二章 数据类型
  7. asp.net ajax 检测用户名是否可用代码
  8. JS中的onclick事件
  9. Unity DoTween 动画使用案例
  10. Java代码风格和在idea中的一些设置
  11. 架构(三)MongoDB安装配置以及集群搭建
  12. 第7章 Linux上配置RAID
  13. vdom,diff,key 算法的了解
  14. 深度学习(七)U-Net原理以及keras代码实现医学图像眼球血管分割
  15. lintcode-14-二分查找
  16. 8086实时时钟实验(一)——《x86汇编语言:从实模式到保护模式》05
  17. java判断姓是否合格 千家姓
  18. javascript 数组 去重
  19. 远程服务器上的weblogic项目管理(二)发布完成后如何重启weblogic容器
  20. L2-014. 列车调度 (DP)

热门文章

  1. python 将歌词解析封装成类,要求:提供一个方法(根据时间返回歌词) - 提示:封装两个类:歌词类、歌词管理类
  2. python 爬虫基础知识(继续补充)
  3. Vue2.5入门-2
  4. (数据科学学习手札53)Python中tqdm模块的用法
  5. 记账APP(5)
  6. OpenFlow1.3.3 学习记录(持续更新)
  7. document ready
  8. 20170531 课堂实践 MyOD
  9. 20155234 2016-2017-2 《Java程序设计》第2周学习总结
  10. 20155235 《Java程序设计》 实验一 Java开发环境的熟悉(Linux + Eclipse)