AI大法之C语言哈希表算法比较两个文件去重
最近朋友在工作上遇到了一个问题,经常需要比对两个文件,筛选出文件中不同的订单号。比如有两个文件:计费.txt 和 受理.txt,文件中每一行都是一个订单号,需要找出计费.txt文件中有而受理.txt文件中没有的单号和计费.txt文件中没有而受理.txt文件中有的单号。
虽然有点绕,但仔细一看不就是简单的去重问题吗。于是我就说,这都2024年了,你把这两个文件上传给豆包、文心一言、kimi这些AI模型,直接让AI帮你找出来不就完事了么。结果并没有想象的那么顺利,由于文件行数不确定,大致在1W-20W行不等,上传给AI时,只给你加载一半数据,也不知道是不是没开会员的原因,想白嫖AI这条路算是行不通了。
于是我提出,干脆写个shell脚本去做这个操作呗。但朋友嫌弃shell脚本太慢了,想让我用C语言帮忙写一个,并请我喝奶茶。我心想这事情简单,有奶茶喝我就给你干了。
刚开始思路是,打开一个文件读一行,跟另一个文件每一行比,比完发现没有重复就存到一个新文件。后面一想,这样做文件行数一多,效率肯定极慢。于是问了问豆包,有什么好办法,豆包给出了个哈希表算法的建议。当了这么久牛马了,现在有了AI这个牛马,我肯定是不会自己从零开始撸代码的了,先让AI帮我写一段。
我copy过来,果然不出所料,编译都编不过。返回来质问AI,AI又老老实实给我整了一段,我找朋友要了两个测试数据,一测试发现不行,然后又让它改,然后给他提了一系列要求、比如哈希碰撞处理什么的,就这么一步步在我的调教下,终于写出了一段能用的代码。大家如果用得上可自取:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h> // 用于isspace函数#define MAX_LINE_LENGTH 1024
#define HASH_TABLE_SIZE 100000typedef struct Node {char *singleNumber;struct Node *next;
} Node;Node *hashTable[HASH_TABLE_SIZE];// 函数声明
unsigned int hashFunction(const char *str);
void insertHash(Node **hashTable, const char *singleNumber);
int containsHash(Node **hashTable, const char *singleNumber);
void freeHashTable(Node *hashTable[]);
int isNotBlankLine(const char *line);
char* trim(const char *str);int generaFile(const char *filename1, const char *filename2)
{FILE *file1, *file2, *outputfd;char output_filename[1024] = {0};strncpy(output_filename, filename2, strlen(filename2) - 4);strcat(output_filename, "_去重后.txt");char line[MAX_LINE_LENGTH];// 初始化哈希表for (int i = 0; i < HASH_TABLE_SIZE; i++) {hashTable[i] = NULL;}// 读取第一个文件并构建哈希表file1 = fopen(filename1, "r");if (!file1) {perror("Error opening file1");return EXIT_FAILURE;}while (fgets(line, MAX_LINE_LENGTH, file1)) {char *trimmedLine = trim(line);if (isNotBlankLine(trimmedLine)) {insertHash(hashTable, trimmedLine);}free(trimmedLine);}fclose(file1);printf("load %s hash finish!\n", filename1);// 读取第二个文件并删除共同的单号file2 = fopen(filename2, "r");outputfd = fopen(output_filename, "w+");if (!file2 || !outputfd) {perror("Error opening file2 or outputfd");return EXIT_FAILURE;}while (fgets(line, MAX_LINE_LENGTH, file2)) {char *trimmedLine = trim(line);line[strcspn(line, "\n")] = 0; // 移除换行符if (isNotBlankLine(trimmedLine) && !containsHash(hashTable, trimmedLine)) { // 没有找到相同的且不是空行fputs(trimmedLine, outputfd);fputc('\n', outputfd); // 使用fputc确保只写入一个换行符}free(trimmedLine);}fclose(file2);fclose(outputfd);// 释放哈希表freeHashTable(hashTable);return EXIT_SUCCESS;
}int isNotBlankLine(const char *line) {// 检查每一字符是否都是空白字符,如果是,则返回0,否则返回1while (*line) {if (!isspace((unsigned char)*line)) {return 1;}line++;}return 0;
}char* trim(const char *str) {if (str == NULL) return NULL;const char *end;size_t len = strlen(str);// Trim leading spacewhile (isspace((unsigned char)*str)) str++;if (*str == 0) // All spaces?return strdup("");// Trim trailing spaceend = str + len - 1;while (end > str && isspace((unsigned char)*end)) end--;// The len is the number of non-space charslen = (end - str + 1);char *trimmed = (char *)malloc(len + 1);if (trimmed) {snprintf(trimmed, len + 1, "%s", str);trimmed[len] = '\0';}return trimmed;
}int main(int argc, char *argv[])
{char *filename1 = argv[1];char *filename2 = argv[2];if (argc != 3) {printf("请指定要去重的两个文件!\n");printf("用法: ./quchong 文件1 文件2\n");printf("示例:./quchong 受理.txt 计费.txt\n");return 0;}if (generaFile(filename1, filename2) != EXIT_SUCCESS) {printf("%s 去重失败!", filename2);return EXIT_FAILURE;}// 注意:这里应该重新初始化哈希表for (int i = 0; i < HASH_TABLE_SIZE; i++) {hashTable[i] = NULL;}if (generaFile(filename2, filename1) != EXIT_SUCCESS) {printf("%s 去重失败!", filename1);return EXIT_FAILURE;}printf("数据去重完成!\n");return EXIT_SUCCESS;
}// 哈希函数
unsigned int hashFunction(const char *str)
{unsigned int hash = 5381;int c;while ((c = *str++)) {hash = ((hash << 5) + hash) + c; /* hash * 33 + c */}return hash % HASH_TABLE_SIZE;
}// 插入哈希表
void insertHash(Node **hashTable, const char *singleNumber)
{unsigned int index = hashFunction(singleNumber);Node *newNode = (Node *)malloc(sizeof(Node));if (!newNode) {perror("Memory allocation failed");exit(EXIT_FAILURE);}newNode->singleNumber = strdup(singleNumber);if (!newNode->singleNumber) {free(newNode);perror("Memory allocation failed");exit(EXIT_FAILURE);}newNode->next = hashTable[index];hashTable[index] = newNode;
}// 检查哈希表中是否包含某个单号
int containsHash(Node **hashTable, const char *singleNumber)
{unsigned int index = hashFunction(singleNumber);Node *current = hashTable[index];while (current) {if (strcmp(current->singleNumber, singleNumber) == 0) {return 1;}current = current->next;}return 0;
}// 释放哈希表内存
void freeHashTable(Node *hashTable[])
{for (int i = 0; i < HASH_TABLE_SIZE; i++) {Node *current = hashTable[i];while (current) {Node *temp = current;current = current->next;free(temp->singleNumber);free(temp);}}
}
不得不感叹现在AI的强大啊,就几轮对话的功夫就给我写出了一个基本能用的代码,大大提高了我们的工作效率。
相关文章:
AI大法之C语言哈希表算法比较两个文件去重
最近朋友在工作上遇到了一个问题,经常需要比对两个文件,筛选出文件中不同的订单号。比如有两个文件:计费.txt 和 受理.txt,文件中每一行都是一个订单号,需要找出计费.txt文件中有而受理.txt文件中没有的单号和计费.txt…...
Scala 提取器(Extractor)
Scala 提取器(Extractor) Scala 提取器(Extractor)是一个非常有用的特性,它允许你为任何类型定义自定义的解构赋值语法。在Scala中,提取器是一种用于从对象中提取值的工具,它可以帮助你以一种更直观和声明式的方式处理数据。本文将详细介绍Scala提取器的工作原理、使用场景…...
【主机漏洞扫描常见修复方案】:Tomcat安全(机房对外Web服务扫描)
文章目录 引言I SSL/TLS Not ImplementedTomcat 服务器 SSL 证书安装部署(JKS 格式)Tomcat 服务器 SSL 证书安装部署(PFX 格式)HTTP 自动跳转 HTTPS 的安全配置(可选)修复SSL证书版本低II 主机漏洞扫描常见修复方案Apache JServ protocol serviceSlow HTTP DEnial of Ser…...
MySQL数据库之——事务(Transaction)详解
一、MySQL 事务定义 MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在银行管理系统中,用户张三向李四账户转账的操作,账户转账是一个完整的业务,最小的单元,不可再分,这样,…...
LabVIEW提高开发效率技巧----事件日志记录
在LabVIEW开发中,集成事件日志记录系统是提升程序调试效率和确保系统运行稳定的关键步骤。通过记录关键操作和异常事件,开发人员可以快速定位问题、优化程序性能,并确保系统的稳定性和可靠性。 1. 事件日志的作用 事件日志是指在程序运行过…...
整合XXL-Job任务调度平台
创建数据库 tables_xxl_job.sql 引入依赖 <dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactId><version>2.4.0</version> </dependency>编写配置文件 server:port: 8081xxl:job:admin:# 这…...
hi3536上ffmpeg带rtmp移植
1.下载ffmpeg-4.1.3版本源码包 用下面的脚本进行configure: ./configure \--target-oslinux \--prefix./libs/ \--enable-cross-compile \--archarm \--ccarm-hisiv500-linux-gcc \--cross-prefixarm-hisiv500-linux- \--nmarm-hisiv500-linux-nm \--enable-share…...
在PHP中,读取大文件
在PHP中,读取大文件可以采用以下几种方法: 1. 使用fopen和fread函数:这是最基本的文件读取方法,可以逐行读取大文件。首先使用fopen函数打开文件,然后使用fread函数指定读取的字节数,逐行读取文件内容并进…...
N-gram详解
文章目录 一、什么是N-gram?二、N-gram的种类三、优缺点PS:补充 一、什么是N-gram? 在自然语言处理中,n-gram是一种重要的文本表示方法。n-gram是指给定文本中连续的n个项目,这些项目可以是声音、单词、字符或者像素等。n-gram模型常常用于…...
电路中的电源轨及地的区别和处理
电源轨 VCC 通常代指正电源供电轨。在大多数数字和模拟电路中,VCC代表电路中的正电源端。VCC提供电路所需的正电压,通常是用来驱动晶体管、集成电路。 VDD 相对与VCC的正电源供应,VDD更常用于表示数字电路中的正电源引脚。VDD常见于集成电…...
k8s可以部署私有云吗?私有云部署全攻略
k8s可以部署私有云吗?K8S可以部署私有云。Kubernetes是一个开源的容器编排引擎,能够自动化容器的部署、扩展和管理,使得应用可以在各种环境中高效运行。通过使用Kubernetes,企业可以在自己的数据中心或私有云环境中搭建和管理容器…...
编辑器资源管理器
解释 EditorResMgr 是一个用于在 Unity 编辑器中加载资源的管理器。它通过 Unity 编辑器的 API (AssetDatabase) 进行资源加载,但仅在开发和编辑模式下可用,不能在最终发布的游戏中使用。这种工具通常用来在开发过程中快速加载编辑器中的资源࿰…...
高性能数据分析利器DuckDB在Python中的使用
DuckDB具有极强的单机数据分析性能表现,功能丰富,具有诸多拓展插件,且除了默认的SQL查询方式外,还非常友好地支持在Python、R、Java、Node.js等语言环境下使用,特别是在Python中使用非常的灵活方便。 安装 pip insta…...
IAR全面支持旗芯微车规级MCU,打造智能安全的未来汽车
中国上海,2024年10月18日 — 在全球汽车电子快速发展的今天,IAR与苏州旗芯微半导体有限公司(以下简称“旗芯微”)联合宣布了一项激动人心的合作——IAR Embedded Workbench for Arm 9.60.2版本现已全面支持旗芯微车规级MCU&#x…...
**深入浅出:TOGAF中的应用架构**
摘要: 在企业架构(EA)领域,TOGAF(The Open Group Architecture Framework)是一个广泛应用的框架。本文将带你深入了解TOGAF中的应用架构,帮助你理解其核心概念和实际应用。无论你是初学者还是有…...
Pytorch学习--DataLoader的使用
一、DataLoader简介 DataLoader官网 重要参数:画红框的参数 dataset: 作用:表示要加载的数据集。DataLoader通过该参数从数据集中读取数据。类型:Dataset,即PyTorch定义的Dataset类,用于封装数据并提供数据索引的功…...
代购系统界的“数据大厨”:定制API数据处理,烹饪出美味佳肴
在这个代购的盛宴中,每一位代购者都是一位大厨,他们用数据作为食材,用代码作为烹饪技巧,烹饪出一道道令人垂涎的美味佳肴。今天,就让我们走进代购界“数据大厨”的厨房,看看他们是如何定制API数据处理&…...
二十、Innodb底层原理与Mysql日志机制深入剖析
文章目录 一、MySQL的内部组件结构1、Server层1.1、连接器1.2、查询缓存1.3、分析器1.4、优化器1.5、执行器 2、存储引擎层 二、Innodb底层原理与Mysql日志机制1、redo log重做日志关键参数2、binlog二进制归档日志2.1、binlog日志文件恢复数据 3、undo log回滚日志4、错误日志…...
数据库设计与管理的要点详解
目录 前言1 数据库设计的基础:清晰的事实表1.1 确保数据的一致性和完整性1.2 优化查询性能 2 权限问题与数据问题的区分2.1 确认权限问题2.2 确认数据问题 3 视图与存储过程的合理使用3.1 视图的作用与应用3.2 存储过程的应用与优化 4 数据库操作日志的设计4.1 确保…...
国家科技创新2030重大项目
国家科技创新2030重大项目涵盖多个领域,例如:量子信息、人工智能、深海空间站、天地一体化信息网络、大飞机、载人航天与月球探测、脑科学与类脑研究、健康保障等,这些项目旨在解决制约我国经济社会发展的重大科技瓶颈问题,提升国…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...
论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...
通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...
