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

文章目录

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

前言

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

功能要求

一份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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

windows server 2022 启用SYN攻击保护

2023.12.28 SYN攻击是什么&#xff1a; SYN攻击是黑客攻击的常用手段&#xff0c;也是最容易被利用的一种攻击手法&#xff0c;属于DDoS攻击的一种。它利用TCP协议缺陷&#xff0c;通过发送大量的半连接请求&#xff0c;耗费CPU和内存资源。 SYN攻击包括大量TCP连接的第一个包&…

竞赛保研 基于大数据的股票量化分析与股价预测系统

文章目录 0 前言1 课题背景2 实现效果3 设计原理QTChartsarma模型预测K-means聚类算法算法实现关键问题说明 4 部分核心代码5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于大数据的股票量化分析与股价预测系统 该项目较为新颖…

【c++】使用vector存放键值对时,明明给vector的不同键赋了不同的值,但为什么前面键的值会被后面键的值给覆盖掉?

错误描述 运行程序得到结果如下图所示&#xff08;左边是原始数据&#xff0c;xxml文件中真实数据的样子&#xff0c;右图是程序运行得到的结果结果&#xff09;&#xff1a; 对比以上两图可以发现&#xff0c;右图中两个实例的三个属性值都来自左图中的第二个User实例&#x…

微信商家转账到零钱开通技巧,模板下载

商家转账到零钱是什么&#xff1f; 【商家转账到零钱】功能整合了微信支付之前的【企业付款到零钱】【批量转账到零钱】功能&#xff0c;支持批量对外转账&#xff0c;对有批量对用户付款需求的应用场景更友好&#xff0c;操作便捷。如果你的应用场景是单付款场景的话&#xf…

方太厨电,在创新科技中看见烟火人间

人类的历史&#xff0c;就是一部创新的历史。科普作者马特里德利在《创新的起源&#xff1a;一部科学技术进步史》写道&#xff1a;能源是所有创新之源。 火的发明和使用&#xff0c;就是一种创新&#xff0c;人类第一次通过控制热量的转换来做功&#xff0c;依靠火来取暖和烹饪…

介绍几种mfc140u.dll丢失的解决方法,找不到msvcp140.dll要怎么处理

如果你在使用电脑时遇到mfc140u.dll丢失错误时&#xff0c;这可能会导致程序无法正常运行&#xff0c;但是大家不必过于担心。今天的这篇文章本将为你介绍几种mfc140u.dll丢失的解决方法&#xff0c;找不到msvcp140.dll要怎么处理的一些解决方法。 一.mfc140u.dll文件缺失会有什…

使用IDEA创建maven java项目(hello word)(1.8)

参考资料&#xff1a; idea创建java项目_使用IDEA创建java项目&#xff08;hello word&#xff09;-CSDN博客 ​ 本文代码工程下载链接&#xff1a; https://download.csdn.net/download/xijinno1/87441597 ​ 前提:已安装好jdk,配置好环境变量。我使用的是java 8&#xff08;…

毫秒格式化

## 计算当前毫秒数&#xff1a; const [start,setStart] useState(new Date().getTime())useEffect(()>{setInterval(()>{setCurrMill(new Date().getTime()-start)},1)},[]) ## 格式化毫秒 function formatMilliseconds(milliseconds) {const totalSeconds Math.flo…

IPD-PDP产品开发流程-PDT产品开发计划Charter文档模板(word)4

今天继续为您分享PDT的产品开发计划Charter模板的内容。 Charter任务书模板内容9&#xff1a;资料开发计划 在IPD运作时&#xff0c;配套资料的开发也是非常重要的内容&#xff0c;尤其是产品发布、上市的时候需要配套的产品资料包非常全面&#xff0c;所以在Charter中也要列出…

面试官:了解CountDownLatch吗

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一份大厂面试资料《史上最全大厂面试题》&#xff0c;Springboot、微服务、算法、数据结构、Zookeeper、Mybatis、Dubbo、linux、Kafka、Elasticsearch、数据库等等 …

Java(算术,自增自减,赋值,关系,逻辑,三元)运算符,运算符的优先级,隐式转换,强制转换,字符串的+。

文章目录 1.运算符和表达式运算符&#xff1a;表达式&#xff1a; 2.算术运算符练习&#xff1a;数值拆分 3.隐式转换概念&#xff1a;简单记忆&#xff1a;两种提升规则&#xff1a;取值范围从小到大的关系&#xff1a; 4.隐式转换的练习案例一&#xff1a;案例二&#xff1a;…

HTML进阶

列表、表格、表单 文章目录 列表、表格、表单01-列表无序列表有序列表定义列表 02-表格表格结构标签-了解合并单元格 03-表单input 标签input 标签占位文本单选框上传文件多选框下拉菜单文本域label 标签按钮 04-语义化无语义的布局标签有语义的布局标签 05-字符实体 01-列表 …

排序整形数组--------每日一题

大家好这是今年最后的一篇了&#xff0c;感谢大家的支持&#xff0c;新的一年我会更加努力地。 文章目录 目录 文章目录 题⽬描述&#xff1a; 输⼊10个整数&#xff0c;然后使⽤冒泡排序对数组内容进⾏升序排序&#xff0c;然后打印数组的内容 一、题目解读 冒泡排序是⼀种基础…

记录 Docker 中安装 ROS2

目录 1 安装 Docker 2 安装 ROS2 3 启动 Docker 4 测试 ROS2 环境 1 安装 Docker 1. 更新软件包sudo apt updatesudo apt upgrade2. 安装 docker 依赖sudo apt-get install ca-certificates curl gnupg lsb-release3. 添加 docker 官方 GPG 密钥curl -fsSL http://mirror…

HarmonyOS4.0系统性深入开发07创建一个ArkTS卡片

创建一个ArkTS卡片 在已有的应用工程中&#xff0c;创建ArkTS卡片&#xff0c;具体操作方式如下。 创建卡片。 根据实际业务场景&#xff0c;选择一个卡片模板。 在选择卡片的开发语言类型&#xff08;Language&#xff09;时&#xff0c;选择ArkTS选项&#xff0c;然后单…

mxxWechatBot微信机器人V2使用教程(图文)最全最详细

大家伙&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。 先看这里 mxxWechatBot功能列表一、前言二、适用人群三、准备工作四、获取账号五、下载资料 六、安装相关软件七、启动客户端八、注入并启动微信九、机器人的基本配置十、自定义接口开发 …

spring核心与思想

spring核心与思想 Spring 是什么&#xff1f;什么是容器&#xff1f;什么是 IoC&#xff1f;传统程序开发传统程序开发的缺陷解决传统开发中的缺陷控制反转式程序开发对⽐总结规律 理解 Spring IoCDI 概念说明 Spring 是什么&#xff1f; Spring 指的是 Spring Framework&…

子网划分问题(实战超详解)_主机分配地址

文章目录: 子网划分的核心思想 第一步,考虑借几位作为子网号 第二步,确定子网的网络地址 第三步,明确网络地址,广播地址,可用IP地址范围 一些可能出现的疑问 实战 题目一 子网划分的核心思想 网络号不变,借用主机号来产生新的网络 划分前的网络:网络号主机号 划分后的网络:原网…

MapboxGL请求加载512尺寸瓦片

作者&#xff1a;yx 文章目录 前言一、关键代码二、完整代码三、结果验证 前言 平常我们使用更多的是256* 256尺寸的瓦片出图&#xff0c;但有的客户需要以512* 512尺寸大小的瓦片出图&#xff0c;对于leaflet可以直接修改tilesize参数为512&#xff0c;例如&#xff1a; 但是…

网络通信-入门1

网口框架 100M 2. 物理层解读 2.1 同步的方法&#xff1a;编码 为了让接收方在没有外部时钟参考的情况也能确定每一位的起始、结束和中间位置&#xff0c;在传输信号时不直接采用二进制编码。在 10BASE-T 的传输方式中采用曼彻斯特编码&#xff0c;在 100BASE-T 中则采用 4B/…