#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#define MAX_WORD_LEN (30)
#define MAX_FILE_LEN (128)
FILE * fdest;
typedef struct
{
char word[MAX_WORD_LEN];
int count;
} item_t;
typedef struct node {
item_t item;
struct node * left;
struct node * right;
} node_t;
typedef node_t * Tree;
Tree * init_tree(Tree * ptree) {
*ptree = NULL;
return ptree;
}
bool is_tree_empty(const Tree * ptree) {
return (*ptree == NULL);
}
bool is_tree_full(const Tree * ptree) {
node_t * pnode = (node_t *) malloc(sizeof(node_t));
if (pnode == NULL) {
return true;
}
else {
free(pnode);
return false;
}
}
bool add_word(const char * word, Tree * ptree) {
if (is_tree_full(ptree)) {
return false;
}
int cmp;
while (*ptree != NULL) {
int cmp = strcmp(word, (*ptree)->item.word);
if (cmp == 0) {
(*ptree)->item.count++;
return true;
}
else if (cmp < 0) {
ptree = &((*ptree)->left);
}
else {
ptree = &((*ptree)->right);
}
}
item_t item;
strncpy(item.word, word, MAX_WORD_LEN);
item.count = 1;
node_t * pnode = (node_t *) malloc(sizeof(node_t));
if (pnode == NULL) {
fprintf(stderr, "内存不足!\n");
return false;
}
pnode->item = item;
pnode->left = NULL;
pnode->right = NULL;
*ptree = pnode;
return true;
}
bool del_word(const char * word, Tree * ptree) {
while (*ptree != NULL) {
int cmp = strcmp(word, (*ptree)->item.word);
if (cmp == 0) {
node_t * right = (*ptree)->right;
node_t * tmp = (*ptree);
*ptree = (*ptree)->left;
while ((*ptree)->right != NULL) {
ptree = &((*ptree)->right);
}
(*ptree)->right = right;
free(tmp);
return true;
}
else if (cmp < 0) {
ptree = &((*ptree)->left);
}
else {
ptree = &((*ptree)->right);
}
}
return false;
}
bool is_in_tree(const char * word, const Tree * ptree) {
node_t * pnode = *ptree;
while (pnode != NULL) {
int cmp = strcmp(word, pnode->item.word);
if (cmp == 0) {
return true;
}
else if (cmp < 0) {
pnode = pnode->left;
}
else {
pnode = pnode->right;
}
}
return false;
}
void apply2node(const char * word, const Tree * ptree, void (*fn)(item_t)) {
node_t * pnode = *ptree;
while (pnode != NULL) {
int cmp = strcmp(word, pnode->item.word);
if (cmp == 0) {
(*fn)(pnode->item);
return;
}
else if (cmp < 0) {
pnode = pnode->left;
}
else {
pnode = pnode->right;
}
}
return;
}
void apply2all(const Tree * ptree, void (*fn)(item_t)) {
node_t * pnode = *ptree;
if (pnode == NULL) {
return;
}
apply2all(&(pnode->left), fn);
(*fn)(pnode->item);
apply2all(&(pnode->right), fn);
}
void del_all(Tree * ptree) {
node_t * pnode = *ptree;
del_all(&(pnode->left));
del_all(&(pnode->right));
free(pnode);
}
void print_menu(void) {
puts("/***************************/");
puts(" 选项:");
puts("---------------------------");
puts("a.列出所有的单词及出现的次数");
puts("b.寻找一个单词在文中出现的次数");
puts("q.退出");
puts("---------------------------");
puts("/***************************/");
printf("请选择: ");
}
int get_option(void) {
print_menu();
int opt;
while ((opt = getchar()) != 'a' && opt != 'b' && opt != 'q') {
printf("无效选择,请重试: ");
while (getchar() != '\n')
continue;
}
while (getchar() != '\n')
continue;
return opt;
}
void print_word_count(item_t item) {
fprintf(fdest,"%s 出现:%d次\n", item.word, item.count);
}
char * to_lower_case(char * string) {
char * retval = string;
for (; *string != '\0'; string++) {
*string = tolower(*string);
}
return retval;
}
char * get(char * string, int n) {
char * retval = fgets(string, n, stdin);
for (; *string != '\0'; string++) {
if (*string == '\n') {
*string = '\0';
break;
}
}
return retval;
}
int main(int argc, char *argv[])
{
FILE * fp;
char source[MAX_FILE_LEN];
char dest[MAX_FILE_LEN];
char way[2];
puts(" 英文词频统计程序 ***Powered By Kori");
puts("**********************************************************");
printf("输入需要统计词频的文件: ");
get(source, MAX_FILE_LEN);
puts("");
printf("输入写入统计数据文件: ");
get(dest, MAX_FILE_LEN);
puts("");
printf("输入统计数据写入方式(a代表文件末尾追加,w代表覆盖写入):");
way[1]='\0';
while ((way[0]=getchar()) != 'a' && way[0] != 'w') {
puts("");
printf("%s",way);
printf("是无效选择,请重试: ");
while (getchar() != '\n')
continue;
}
getchar();
if ((fp = fopen(source, "r")) == NULL)
{
puts("");
fprintf(stderr, "无法打开读取的文件 %s.\n", source);
exit(EXIT_FAILURE);
}
if ((fdest = fopen(dest, way)) == NULL)
{
puts("");
fprintf(stderr, "无法打开写入的文件 %s.\n", dest);
exit(EXIT_FAILURE);
}
char tmp[MAX_WORD_LEN];
Tree words;
Tree * ptree = init_tree(&words);
while (fscanf(fp, "%s", tmp) == 1) {
to_lower_case(tmp);
for(int i = 0;i < MAX_WORD_LEN; i++)
if(tmp[i]>'z'||tmp[i]<'a')
{
tmp[i]='\0';
break;
}
if (!add_word(tmp, ptree)) {
puts("");
fprintf(stderr, "未能将 %s 添加到查找范围中.\n",tmp);
exit(1);
}
}
int ch;
char word[MAX_WORD_LEN];
while ((ch = get_option()) != 'q') {
if (ch == 'a') {
puts("");
puts("正在处理中,请稍后......");
apply2all(ptree, print_word_count);
puts("");
puts("成功执行操作!请关闭程序后查看!");
} else if (ch == 'b') {
puts("");
printf("输入要搜索的单词: ");
get(word, 30);
puts("");
puts("正在处理中,请稍后......");
apply2node(word, ptree, print_word_count);
puts("");
puts("成功执行操作!请关闭程序后查看!");
}
puts("");
}
fclose(fp);
fclose(fdest);
}
词频统计程序C语言实现
最新推荐文章于 2022-08-08 07:10:30 发布