在這個問題中: Detecting duplicate lines on file using c 我可以檢測到重複的行,但我們如何從我們的文件中刪除此行?使用C刪除文件中的所有重複行C
謝謝。
編輯:要添加我的代碼:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct somehash {
struct somehash *next;
unsigned hash;
char *mem;
};
#define THE_SIZE 100000
struct somehash *table[THE_SIZE] = { NULL,};
struct somehash **some_find(char *str, unsigned len);
static unsigned some_hash(char *str, unsigned len);
int main (void)
{
char buffer[100];
struct somehash **pp;
size_t len;
FILE * pFileIn;
FILE * pFileOut;
pFileIn = fopen("in.csv", "r");
pFileOut = fopen("out.csv", "w+");
if (pFileIn==NULL) perror ("Error opening input file");
if (pFileOut==NULL) perror ("Error opening output file");
while (fgets(buffer, sizeof buffer, pFileIn)) {
len = strlen(buffer);
pp = some_find(buffer, len);
if (*pp) { /* found */
fprintf(stderr, "Duplicate:%s\n", buffer);
}
else
{ /* not found: create one */
fprintf(stdout, "%s", buffer);
fprintf(pFileOut, "%s", buffer);
*pp = malloc(sizeof **pp);
(*pp)->next = NULL;
(*pp)->hash = some_hash(buffer,len);
(*pp)->mem = malloc(1+len);
memcpy((*pp)->mem , buffer, 1+len);
}
}
return 0;
}
struct somehash **some_find(char *str, unsigned len)
{
unsigned hash;
unsigned short slot;
struct somehash **hnd;
hash = some_hash(str,len);
slot = hash % THE_SIZE;
for (hnd = &table[slot]; *hnd ; hnd = &(*hnd)->next) {
if ((*hnd)->hash != hash) continue;
if (strcmp((*hnd)->mem , str)) continue;
break;
}
return hnd;
}
static unsigned some_hash(char *str, unsigned len)
{
unsigned val;
unsigned idx;
if (!len) len = strlen(str);
val = 0;
for(idx=0; idx < len; idx++) {
val ^= (val >> 2)^(val << 5)^(val << 13)^str[idx]^0x80001801;
}
return val;
}
但在輸出文件中,我們總能得到第一次出現!
編輯2:澄清:目的是在輸入文件中查找所有重複項。當輸入中有多條線的實例時,該線不應出現在輸出的所有處。意圖不僅僅是刪除的重複的行,因此每行只出現一次,而是刪除全部行的實例(如果該行在輸入中重複)。
另一方面,SHA256哈希長度爲32字節,可能比平均線長度長,*計算*它們將在'O(N)'項上大量增加常量。 – zwol 2012-04-17 23:14:10
@Zack:好點。見編輯的答案。 – 2012-04-17 23:46:09
@JerryCoffin:謝謝,我發佈了我的代碼,問題是始終將第一個匹配項添加到文件中,導致我們第一次對它進行哈希處理,我們需要將其插入到文件中。 – iPadDevloperJr 2012-04-18 18:12:57