C语言实现关键字匹配算法(复制即用)

news2025/1/24 2:23:32

文章目录

  • 前言
  • 功能要求
  • 运行截图
  • 全部代码

前言

无套路,均已上机通过,求个关注求个赞,提供答疑解惑服务。

功能要求

一份C源代码存储在一个文本文件中,请统计该文件中关键字出现的频度,并按此频度对关键字进行排序。要求:

  • 从文本文件InFile.txt读取C源代码,从文本文件Key.txt读取关键字列表。
  • 分别采用如下不同的查找策略进行频度统计:
    • 链式存储上的顺序查找;
    • 基于链地址法的哈希查找。
  • 基于快速排序实现关键字排序。
  • 不论采取哪种查找和排序策略,完成功能均相同。
    • 关键字统计:依次从关键字列表Key.txt中读取关键字,若该关键字未在文本文件InFile.txt中出现,则将其频度计为0;每检索到一次该关键字,则将其频度增加1。统计结束后,将所有关键字及其频度按关键字列表顺序写入文本文件中。其中,无论关键字列表中的关键字是否出现都要计数。不同查找策略所获得的结果分别写入不同的文件(OutFile1.txt,OutFile2.txt)。
    • 关键字排序:根据关键字出现的频度对所有关键字进行从高到低排序,舍弃关键字列表中未出现的关键字。如果关键字出现的频度相等,则按照关键字的首字母从小到大排序,将排序后的关键字及其频度写入文本文件(OutFile3.txt)中。
  • 设计菜单,实现上述功能。

运行截图

在这里插入图片描述

全部代码

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

#define MAX_KEYWORDS 100
#define MAX_KEYWORD_LENGTH 50
#define HASH_TABLE_SIZE 101

typedef struct {
    char keyword[MAX_KEYWORD_LENGTH];
    int frequency;
} KeywordInfo;

typedef struct HashNode {
    KeywordInfo data;
    struct HashNode *next;
} HashNode;

typedef struct {
    HashNode *table[HASH_TABLE_SIZE];
} HashTable;

int compareKeywords(const void *a, const void *b) {
    const KeywordInfo *keywordA = (const KeywordInfo *)a;
    const KeywordInfo *keywordB = (const KeywordInfo *)b;

    if (keywordB->frequency != keywordA->frequency) {
        return keywordB->frequency - keywordA->frequency;
    }

    return strcmp(keywordA->keyword, keywordB->keyword);
}

void initializeHashTable(HashTable *hashTable) {
    int i;
    for (i = 0; i < HASH_TABLE_SIZE; i++) {
        hashTable->table[i] = NULL;
    }
}

unsigned int hashFunction(const char *str) {
    unsigned int hash = 0;
    while (*str) {
        hash = (hash << 5) + *str++;
    }
    return hash % HASH_TABLE_SIZE;
}

HashNode *searchHashTable(HashTable *hashTable, const char *keyword) {
    unsigned int hashValue = hashFunction(keyword);
    HashNode *current = hashTable->table[hashValue];

    while (current != NULL) {
        if (strcmp(current->data.keyword, keyword) == 0) {
            return current;
        }
        current = current->next;
    }

    return NULL;
}

void insertHashTable(HashTable *hashTable, const KeywordInfo *keywordInfo) {
    unsigned int hashValue = hashFunction(keywordInfo->keyword);
    HashNode *newNode = (HashNode *)malloc(sizeof(HashNode));

    if (newNode == NULL) {
        printf("内存分配失败\n");
        exit(1);
    }

    newNode->data = *keywordInfo;
    newNode->next = hashTable->table[hashValue];
    hashTable->table[hashValue] = newNode;
}

void freeHashTable(HashTable *hashTable) {
    int i;
    for (i = 0; i < HASH_TABLE_SIZE; i++) {
        HashNode *current = hashTable->table[i];
        while (current != NULL) {
            HashNode *next = current->next;
            free(current);
            current = next;
        }
    }
}

void countKeywordsSequential(FILE *file, char *keywords[], int numKeywords, KeywordInfo keywordInfo[]) {
    char line[1024];

    rewind(file);

    while (fgets(line, sizeof(line), file) != NULL) {
        for (int i = 0; i < numKeywords; i++) {
            char *pos = strstr(line, keywords[i]);
            while (pos != NULL) {
                if ((pos == line || !isalpha(pos[-1])) && !isalpha(pos[strlen(keywords[i])])) {
                    keywordInfo[i].frequency++;
                }
                pos = strstr(pos + 1, keywords[i]);
            }
        }
    }
}

void countKeywordsHash(FILE *file, HashTable *hashTable, char *keywords[], int numKeywords, KeywordInfo keywordInfo[]) {
    char line[1024];

    rewind(file);

    while (fgets(line, sizeof(line), file) != NULL) {
        for (int i = 0; i < numKeywords; i++) {
            char *pos = strstr(line, keywords[i]);
            while (pos != NULL) {
                if ((pos == line || !isalpha(pos[-1])) && !isalpha(pos[strlen(keywords[i])])) {
                    // 检查哈希表中是否已存在该关键字的节点
                    HashNode *existingNode = searchHashTable(hashTable, keywords[i]);

                    if (existingNode != NULL) {
                        // 如果已存在,则更新哈希表中节点的频度
                        existingNode->data.frequency++;
                    } else {
                        // 如果不存在,则插入新节点到哈希表
                        KeywordInfo newKeywordInfo = { .frequency = 1 };
                        strcpy(newKeywordInfo.keyword, keywords[i]);

                        insertHashTable(hashTable, &newKeywordInfo);
                    }

                    // 更新数组中的频度
                    keywordInfo[i].frequency++;
                }
                pos = strstr(pos + 1, keywords[i]);
            }
        }
    }
}

void writeKeywordStats(FILE *outputFile, KeywordInfo keywordInfo[], int numKeywords) {
    for (int i = 0; i < numKeywords; i++) {
        fprintf(outputFile, "%s: %d\n", keywordInfo[i].keyword, keywordInfo[i].frequency);
    }
}

void writeSortedKeywordStats(FILE *outputFile, KeywordInfo keywordInfo[], int numKeywords) {
    for (int i = 0; i < numKeywords; i++) {
        if (keywordInfo[i].frequency > 0) {
            fprintf(outputFile, "%s: %d\n", keywordInfo[i].keyword, keywordInfo[i].frequency / 2);
        }
    }
}

void writeHashTableStats(FILE *outputFile, HashTable *hashTable, char *keywords[], int numKeywords) {
    for (int i = 0; i < numKeywords; i++) {
        HashNode *node = searchHashTable(hashTable, keywords[i]);
        fprintf(outputFile, "%s: %d\n", keywords[i], (node != NULL) ? node->data.frequency : 0);
    }
}

void sortKeywords(KeywordInfo keywordInfo[], int numKeywords) {
    qsort(keywordInfo, numKeywords, sizeof(KeywordInfo), compareKeywords);
}

int main(void) {
    FILE *keywordFile, *codeFile;
    FILE *outputFile1, *outputFile2, *outputFile3;
    char *keywords[MAX_KEYWORDS];
    int numKeywords = 0;
    char tempKeyword[MAX_KEYWORD_LENGTH];
    KeywordInfo keywordInfo[MAX_KEYWORDS];
    HashTable hashTable;

    // 打开文件
    keywordFile = fopen("Key.txt", "r");
    codeFile = fopen("InFile.txt", "r");
    outputFile1 = fopen("OutFile1.txt", "w");
    outputFile2 = fopen("OutFile2.txt", "w");
    outputFile3 = fopen("OutFile3.txt", "w");

    if (keywordFile == NULL || codeFile == NULL || outputFile1 == NULL || outputFile2 == NULL || outputFile3 == NULL) {
        printf("无法打开文件\n");
        return 1;
    }

    // 读取关键字列表
    while (fscanf(keywordFile, "%s", tempKeyword) != EOF && numKeywords < MAX_KEYWORDS) {
        keywords[numKeywords] = (char *)malloc(strlen(tempKeyword) + 1);
        strcpy(keywords[numKeywords], tempKeyword);
        numKeywords++;
    }

    // 初始化关键字信息数组
    for (int i = 0; i < numKeywords; i++) {
        strcpy(keywordInfo[i].keyword, keywords[i]);
        keywordInfo[i].frequency = 0;
    }

    // 初始化哈希表
    initializeHashTable(&hashTable);

    int choice;
    do {
        // 显示菜单
        printf("\n菜单:\n");
        printf("1. 顺序查找关键字并统计频度(输出到OutFile1.txt)\n");
        printf("2. 哈希查找关键字并统计频度(输出到OutFile2.txt)\n");
        printf("3. 排序关键字并输出到OutFile3.txt\n");
        printf("4. 退出\n");
        printf("请选择操作: ");
        scanf("%d", &choice);

        switch (choice) {
            case 1:
                // 顺序查找关键字并统计频度
                countKeywordsSequential(codeFile, keywords, numKeywords, keywordInfo);
                writeKeywordStats(outputFile1, keywordInfo, numKeywords);
                break;
            case 2:
                // 哈希查找关键字并统计频度
                countKeywordsHash(codeFile, &hashTable, keywords, numKeywords, keywordInfo);
                writeHashTableStats(outputFile2, &hashTable, keywords, numKeywords);
                break;
            case 3:
                // 排序关键字并输出
                sortKeywords(keywordInfo, numKeywords);
                writeSortedKeywordStats(outputFile3, keywordInfo, numKeywords);
                break;
            case 4:
                // 退出
                break;
            default:
                printf("无效的选项,请重新选择\n");
                break;
        }
    } while (choice != 4);

    // 关闭文件和释放内存
    fclose(keywordFile);
    fclose(codeFile);
    fclose(outputFile1);
    fclose(outputFile2);
    fclose(outputFile3);

    for (int i = 0; i < numKeywords; i++) {
        free(keywords[i]);
    }

    freeHashTable(&hashTable);

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1347204.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Kafka安装及简单使用介绍

&#x1f353; 简介&#xff1a;java系列技术分享(&#x1f449;持续更新中…&#x1f525;) &#x1f353; 初衷:一起学习、一起进步、坚持不懈 &#x1f353; 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正&#x1f64f; &#x1f353; 希望这篇文章对你有所帮助,欢…

政务大数据能力平台建设方案:文件全文30页,附下载

关键词&#xff1a;智慧政务解决方案&#xff0c;智慧政务建设&#xff0c;智慧政务服务平台&#xff0c;智慧政务大数据&#xff0c;数字政务一体化平台。大数据&#xff0c;政务大数据建设 一、智慧政务建设需求 1、政务服务需求&#xff1a;智慧政务建设需要满足人民群众的…

Jenkins 系列:Jenkins 安装(Windows、Mac、Centos)和简介

文章目录 简介发展历史应用场景 Jenkins 安装部署先决条件硬件要求软件包下载war 包部署linux 系统部署mac 系统部署windows 系统部署安装后基本配置解锁自定义 jenkins 插件创建用户配置更新站点 配置文件 简介 Jenkins前身是 Hudson&#xff0c;使用 java 语言开发的自动化发…

基于SpringBoot实现的前后端分离电影评分项目,功能:注册登录、浏览影片、热门影片、搜索、评分、片单、聊天、动态

一、项目介绍 本项目主要基于SpringBoot、Mybatis-plus、MySQL、Redis实现的影片评分项目。 本系统是前后端分离的&#xff0c;分别由三个子项目构成&#xff1a;java服务端、用户前端、管理员管理前端 关键词&#xff1a;springboot java vue mysql reids websocket 毕业设计…

【Leetcode】1154. 一年中的第几天

文章目录 题目思路代码 题目 1154. 一年中的第几天链接 思路 题目要求是给定一个字符串 date&#xff0c;它代表一个日期&#xff0c;采用标准的 YYYY-MM-DD 格式。需要计算这个日期是当年的第几天。 首先&#xff0c;我们可以通过字符串的索引来提取年、月和日的数值&…

python的pywebio库给孩子做加减法数学题

效果展示 程序执行后&#xff0c;打开浏览器&#xff0c;展示一些100以内的加减法混合运算的数学题并输入答案后判断对错&#xff0c;这样倒是省了买教材的钱了。 在题目下方的框中&#xff0c;输入答案&#xff0c;然后点击提交后&#xff0c; 会输出结果 pywebio库介绍 安装…

Resnet BatchNormalization 迁移学习

时间&#xff1a;2015 网络中的亮点&#xff1a; 超深的网络结构&#xff08;突破1000层&#xff09;提出residual模块使用Batch Normalization加速训练&#xff08;丢弃dropout&#xff09; 层数越深效果越好&#xff1f; 是什么样的原因导致更深的网络导致的训练效果更差呢…

计算机组成原理复习7

内存管理 文章目录 内存管理存储器概述存储器的分类按在计算机中的作用&#xff08;层次&#xff09;分类按存储介质分类按存取方式分类按信息的可保存性分类 存储器的性能指标存储容量单位成本存储速度&#xff1a;数据传输率数据的宽度/存储周期 存储器的层次化结构多级存储系…

【实用工具】vim常用命令

快速移动(上下左右箭头可替代) 左移 h 右移 l 下移 j 上移 K在本行操作 0 移动到本行行首 ^ 移动到本行的第一个不是 blank 字符 $ 移动到本行行尾 w 光标移动到下一个单词的开头 e 光标移动到下一个单词的结尾跨行移动光标 nG 光标定位到第n行的行首 gg 光标定位到第一行的…

SPI机制原理+使用

一、概述 SPI全称&#xff08;Service Provider Interface&#xff09;&#xff0c;是JDK内置的一种服务提供发现机制&#xff1b;SPI机制提供了组件发现和注册方式&#xff0c;可以为应用程序提供灵活的插件机制&#xff0c; 主要原理&#xff1a;接口 反射 配置文件。 二、…

Visual Studio 2015 中 SDL2 开发环境的搭建

Visual Studio 2015 中 SDL2 开发环境的搭建 Visual Studio 2015 中 SDL2 开发环境的搭建新建控制台工程拷贝并配置 SDL2 开发文件拷贝 SDL2 开发文件配置 SDL2 开发文件 测试SDL2 开发文件的下载链接 Visual Studio 2015 中 SDL2 开发环境的搭建 新建控制台工程 新建 Win32 …

学习使用echats实现双刻度echarts双Y轴,左右Y轴数据的方法

学习使用echats实现双刻度echarts双Y轴&#xff0c;左右Y轴数据的方法 代码效果图 代码 <!--此示例下载自 https://echarts.apache.org/examples/zh/editor.html?cline-stack&langjs --> <!DOCTYPE html> <html lang"en" style"height: 10…

工业机器人与计算机技术:驱动现代工业变革

工业机器人与计算机技术&#xff1a;驱动现代工业变革 随着科技的飞速发展&#xff0c;工业机器人与计算机技术已经成为现代工业制造的核心驱动力。这两者之间的联系日益紧密&#xff0c;共同推动着工业生产的自动化、智能化和高效化。 一、工业机器人&#xff1a;从机械手臂…

以太坊代币标准解读及相关Dapp的搭建

文章目录 什么是以太坊代币标准1、什么是以太坊2、以太坊代币标准 同质化代币 Dapp 搭建1、MetaMask 的安装2、Ganache 的安装3、实现 ERC-20 代币协议4、前端页面的编写5、部署流程及操作演示 什么是以太坊代币标准 1、什么是以太坊 以太坊&#xff08;Ethereum&#xff09;是…

Linux环境grep搜索方法记录

1 grep grep 命令&#xff0c;用来搜索字符串所在位置&#xff0c;可以具体到不同文件&#xff0c;不同行&#xff1b; 在Linux 下&#xff0c;查看命令释义如下 zhaocubuntu2004:~$ grep --help Usage: grep [OPTION]... PATTERNS [FILE]... Search for PATTERNS in each FI…

安装Hadoop:Hadoop的单机模式、伪分布式模式——备赛笔记——2024全国职业院校技能大赛“大数据应用开发”赛项

前言 Hadoop包括三种安装模式&#xff1a; 单机模式&#xff1a;只在一台机器上运行&#xff0c;存储是采用本地文件系统&#xff0c;没有采用分布式文件系统HDFS&#xff1b;伪分布式模式&#xff1a;存储采用分布式文件系统HDFS&#xff0c;但是&#xff0c;HDFS的名称节点…

【VRTK】【VR开发】【Unity】18-VRTK与Unity UI控制的融合使用

课程配套学习项目源码资源下载 https://download.csdn.net/download/weixin_41697242/88485426?spm=1001.2014.3001.5503 【背景】 VRTK和Unity自身的UI控制包可以配合使用发挥效果。本篇就讨论这方面的实战内容。 之前可以互动的立体UI并不是传统的2D UI对象,在实际使用中…

Mac 安装 Minikube 及解决 “[ERROR ImagePull]: failed to pull image“ 问题

文章目录 1. 引言2. Mac 安装 Docker3. Mac 安装 Minikube4. 拉起集群4.1 启动4.2 验证 5. 参考 1. 引言 Minikube 是一种轻量化的 Kubernetes 集群&#xff0c;旨在帮助开发者和学习者更好地学习和体验 Kubernetes 的功能。它可以在个人计算机的虚拟化环境中快速构建和启动 Ku…

网易有道词典不能截屏翻译,不能联网解决办法

对应版本&#xff1a; win10系统&#xff0c;联想拯救者笔记本&#xff0c;网易有道词典8.10.2.0。 网易有道词典免费下载链接&#xff1a;https://download.csdn.net/download/qq_42755734/88684985 修改代理&#xff1a; youdao.com 0 取消勾选---不更新 效果&#xff1a…

移动应用开发:揭秘内侧APP封装台的高效

在数字化浪席卷下&#xff0c;移应用已经成连接企业与用户纽带。为了抢占市场先机&#xff0c;快速发布高质量的移动应用成为业竞争的关键。侧APP封装平因此而诞生&#xff0c;成为了应开发者的得助手。以下是内侧APP封装台的全面解读&#xff0c;助在应用开发海洋中乘风破浪。…