視頻網(wǎng)站app怎么做的長春做網(wǎng)絡(luò)優(yōu)化的公司
最近朋友在工作上遇到了一個問題,經(jīng)常需要比對兩個文件,篩選出文件中不同的訂單號。比如有兩個文件:計費.txt
和 受理.txt
,文件中每一行都是一個訂單號,需要找出計費.txt
文件中有而受理.txt
文件中沒有的單號和計費.txt
文件中沒有而受理.txt
文件中有的單號。
雖然有點繞,但仔細(xì)一看不就是簡單的去重問題嗎。于是我就說,這都2024年了,你把這兩個文件上傳給豆包
、文心一言
、kimi
這些AI模型,直接讓AI幫你找出來不就完事了么。結(jié)果并沒有想象的那么順利,由于文件行數(shù)不確定,大致在1W-20W行不等,上傳給AI時,只給你加載一半數(shù)據(jù),也不知道是不是沒開會員的原因,想白嫖AI這條路算是行不通了。
于是我提出,干脆寫個shell腳本去做這個操作唄。但朋友嫌棄shell腳本太慢了,想讓我用C語言幫忙寫一個,并請我喝奶茶。我心想這事情簡單,有奶茶喝我就給你干了。
剛開始思路是,打開一個文件讀一行,跟另一個文件每一行比,比完發(fā)現(xiàn)沒有重復(fù)就存到一個新文件。后面一想,這樣做文件行數(shù)一多,效率肯定極慢。于是問了問豆包,有什么好辦法,豆包給出了個哈希表算法的建議。當(dāng)了這么久牛馬了,現(xiàn)在有了AI這個牛馬,我肯定是不會自己從零開始擼代碼的了,先讓AI幫我寫一段。
我copy過來,果然不出所料,編譯都編不過。返回來質(zhì)問AI,AI又老老實實給我整了一段,我找朋友要了兩個測試數(shù)據(jù),一測試發(fā)現(xiàn)不行,然后又讓它改,然后給他提了一系列要求、比如哈希碰撞處理什么的,就這么一步步在我的調(diào)教下,終于寫出了一段能用的代碼。大家如果用得上可自取:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h> // 用于isspace函數(shù)#define MAX_LINE_LENGTH 1024
#define HASH_TABLE_SIZE 100000typedef struct Node {char *singleNumber;struct Node *next;
} Node;Node *hashTable[HASH_TABLE_SIZE];// 函數(shù)聲明
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;}// 讀取第一個文件并構(gòu)建哈希表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;}// 注意:這里應(yīng)該重新初始化哈希表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("數(shù)據(jù)去重完成!\n");return EXIT_SUCCESS;
}// 哈希函數(shù)
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;
}// 釋放哈希表內(nèi)存
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);}}
}
不得不感嘆現(xiàn)在AI的強大啊,就幾輪對話的功夫就給我寫出了一個基本能用的代碼,大大提高了我們的工作效率。