首页 > 编程语言 >编写一个程序,打开和读取一个文本文件,并统计文件中每个单词出现的次数。用改进的二叉查找树存储单词及其出现的次数。程序在读入文件后 会提供一个有三个选项菜单。第一个选项是列出所有的单词和出现的次数。第二

编写一个程序,打开和读取一个文本文件,并统计文件中每个单词出现的次数。用改进的二叉查找树存储单词及其出现的次数。程序在读入文件后 会提供一个有三个选项菜单。第一个选项是列出所有的单词和出现的次数。第二

时间:2024-08-13 23:38:48浏览次数:8  
标签:选项 Node word 单词 次数 printf root

/编写一个程序,打开和读取一个文本文件,并统计文件中每个单词出现的次数。用改进的二叉查找树存储单词及其出现的次数。程序在读入文件后
会提供一个有三个选项菜单。第一个选项是列出所有的单词和出现的次数。第二个选项是让用户输入一个单词,程序报告该单词在文件中出现的次数。
第三个选项是退出
/

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

#define MAX_WORD_LENGTH 100

typedef struct Node
{
    char word[MAX_WORD_LENGTH];
    int count;
    struct Node *left;
    struct Node *right;
} Node;

Node *createNode(const char *word)
{
    Node *newNode = (Node *)malloc(sizeof(Node));
    strcpy(newNode->word, word);
    newNode->count = 1;
    newNode->left = newNode->right = NULL;
    return newNode;
}

Node *insert(Node *root, const char *word)
{
    if (root == NULL)
    {
        return createNode(word);
    }
    if (strcmp(word, root->word) < 0)
    {
        root->left = insert(root->left, word);
    }
    else if (strcmp(word, root->word) > 0)
    {
        root->right = insert(root->right, word);
    }
    else
    {
        root->count++;
    }
    return root;
}

void display(Node *root)
{
    if (root != NULL)
    {
        display(root->left);
        printf("%s: %d\n", root->word, root->count);
        display(root->right);
    }
}

int getCount(Node *root, const char *word)
{
    if (root == NULL)
    {
        return 0;
    }
    if (strcmp(word, root->word) < 0)
    {
        return getCount(root->left, word);
    }
    else if (strcmp(word, root->word) > 0)
    {
        return getCount(root->right, word);
    }
    else
    {
        return root->count;
    }
}

void freeTree(Node *root)
{
    if (root != NULL)
    {
        freeTree(root->left);
        freeTree(root->right);
        free(root);
    }
}

void toLowerCase(char *str)
{
    for (int i = 0; str[i]; i++)
    {
        str[i] = tolower((unsigned char)str[i]);
    }
}

void processFile(const char *filename, Node **root)
{
    FILE *file = fopen(filename, "r");
    if (file == NULL)
    {
        printf("无法打开文件 %s\n", filename);
        return;
    }

    char word[MAX_WORD_LENGTH];
    while (fscanf(file, "%s", word) != EOF)
    {
        toLowerCase(word); // 转换为小写以避免重复
        *root = insert(*root, word);
    }

    fclose(file);
}

int main(int argc,char *argv[])
{
    Node *root = NULL;
    if(argc!=2)
    {
        printf("可执行文件 [查找文件]\n");
    }
    assert(argv[1]);
    processFile(argv[1], &root);
    
    
    int choice;
    do
    {
        printf("\n菜单:\n");
        printf("1. 列出所有单词及出现次数\n");
        printf("2. 查询单词出现次数\n");
        printf("3. 退出\n");
        printf("请选择操作: ");
        scanf("%d", &choice);
        getchar();
        switch (choice)
        {
        case 1:
            printf("单词及出现次数:\n");
            display(root);
            break;
        case 2:
        {
            char queryWord[MAX_WORD_LENGTH];
            printf("请输入要查询的单词: ");
            fgets(queryWord, sizeof(queryWord), stdin);
            queryWord[strcspn(queryWord, "\n")] = 0;
            toLowerCase(queryWord);
            int count = getCount(root, queryWord);
            if (count > 0)
            {
                printf("单词 '%s' 出现次数: %d\n", queryWord, count);
            }
            else
            {
                printf("单词 '%s' 不在文件中。\n", queryWord);
            }
            break;
        }
        case 3:
            printf("退出程序。\n");
            break;
        default:
            printf("无效选择,请重新输入。\n");
            break;
        }
    } while (choice != 3);
    freeTree(root);
    return 0;
}

标签:选项,Node,word,单词,次数,printf,root
From: https://www.cnblogs.com/yesiming/p/18357951

相关文章

  • 英语二【00015】精选单词练习第六天
    英语二【00015】4000+单词精选提炼单词历史学习记录:英语二【00015】精选单词练习历史英语二4500单词表下载第六天练习boring[ˈbɔ:rɪŋ]adj.无聊的,无趣的contribute[kənˈtribjut]vt.&vi.贡献出remove[riˈmu:v]vt.开除;去除manage[ˈmænɪdʒ]vt.......
  • [题解]P3966 [TJOI2013] 单词
    P3966[TJOI2013]单词用\(p[i]\)来表示经过节点\(i\)的字符串个数。那么节点\(u\)的答案就是fail树上,以\(u\)为根的子树的\(p\)之和。由于我们已经计算了\(p[i]\),所以字符串\(i\)作为模式串本身&模式串前缀的情况已经考虑了。还需考虑\(i\)作为模式串后缀的情况,而只有fail树上......
  • 【SQL】参加测试的次数
    目录题目分析代码题目学生表: Students+---------------+---------+|ColumnName|Type|+---------------+---------+|student_id|int||student_name|varchar|+---------------+---------+在SQL中,主键为student_id(学生ID)。该表内的......
  • 【Spring-RabbitMq】设置消费重试次数
    引言在我们实际项目中需要对消息消费的高可用做保证,首先需要做到的就是消息的重试机制,设想一下以下场景:当库存服务处理上游服务发过来的订单消息时,此时服务宕机了,或者网络不可用了,那我这个消息是应该算消费成功还是消费失败呢?显然,我们肯定要对处理不成功的消息进行重试......
  • (111)vivado综合选项--->(11)Vivado综合策略十一
    1目录(a)IC简介(b)数字IC设计流程(c)Verilog简介(d)Vivado综合策略十一(e)结束1IC简介(a)在IC设计中,设计师使用电路设计工具(如EDA软件)来设计和模拟各种电路,例如逻辑电路、模拟电路、数字信号处理电路等。然后,根据设计电路的规格要求,进行布局设计和布线,确定各个电路元件的位置和连......
  • (112)vivado综合选项--->(12)Vivado综合策略十二
    1目录(a)IC简介(b)数字IC设计流程(c)Verilog简介(d)Vivado综合策略十二(e)结束1IC简介(a)在IC设计中,设计师使用电路设计工具(如EDA软件)来设计和模拟各种电路,例如逻辑电路、模拟电路、数字信号处理电路等。然后,根据设计电路的规格要求,进行布局设计和布线,确定各个电路元件的位置和连......
  • 008.Vue3入门,最基础的事件处理,点击按钮增加次数,支持传参
    1、代码如下:<template><h3>内联事件处理群</h3><button@click="addCount1">Add</button><p>{{count1}}</p><button@click="addCount2('hello')">按钮</button><p>{{coun......
  • 151. 反转字符串中的单词【 力扣(LeetCode) 】
    一、题目描述  给你一个字符串s,请你反转字符串中单词的顺序。  单词是由非空格字符组成的字符串。s中使用至少一个空格将字符串中的单词分隔开。  返回单词顺序颠倒且单词之间用单个空格连接的结果字符串。注意:输入字符串s中可能会存在前导空格、尾......
  • 3224. 使差值相等的最少数组改动次数
    原题链接前情提要,结合原题解区的题解题解先简化问题,对于一对数\(a,b\),其中\(a\leqb\),要使其差为\(X\)的操作数是多少?分类讨论1.如果\(b-a==X\),操作数为\(0\)(不操作)2.如果\(X\ltb-a\),操作数为\(1\)(增加a或者减小b)3.如果\(X\in[b-a+1,k-a]\),操作数为\(1\)(增大b......
  • 3229. 使数组等于目标数组所需的最少操作次数
    原题链接题解原题解区写的很详细,所以这里总结一下自己的语言性质1.如果两个数组相等,那么两个数组的差分数组也相等根据这个性质,原题就转换成了对数组\(a\)的差分数组操作(选取两个点\(i,j\)使\(d[i]+1,d[j]-1\)或者\(d[i]-1,d[j]+1\))性质2:差分数组上,有多少加,就有多少......