2016-06-30 2 views
0

행별로 2 개의 csv (거대한 파일)를 비교하고 차이 행을 별도의 파일에 써야합니다. 한 파일의 행은 두 번째 파일의 어느 곳에 나있을 수 있습니다. 전체 행을 비교해야합니다. 포인터가 있습니까? 신속하고 더러운두 개의 큰 CSV 파일을 비교하고 차이점 파일을 얻는 방법

+0

시도한 내용은 무엇입니까? – Imad

+0

와우, 너무 넓습니다.하지만 괜찮은 성능을 원한다면, 중복 된 것을 검색하기 위해 메모리에있는 전체 2 개의 파일을 읽을 필요가 있다고 생각합니다. 행의 필드 순서가 동일하면 2를 사용할 수 있습니다. List Pikoh

답변

0

:

private void DoSomething() 
{ 
    var lines1 = File.ReadAllLines(@"file1.csv"); 
    var lines2 = File.ReadAllLines(@"file2.csv"); 

    var diff1From2 = FindDifferences(lines1, lines2); 
    var diff2From1 = FindDifferences(lines2, lines1); 

    var diffs = new List<string>(diff1From2); 
    diffs.AddRange(diff2From1); 
    File.WriteAllLines(@"file3.csv", diffs); 
} 

private static string[] FindDifferences(string[] linesFirst, string[] linesSecond) 
{ 
    return (from line1 in linesFirst 
    let isLineEqual = linesSecond.Any(line2 => line1 == line2) 
    where isLineEqual == false 
    select line1).ToArray(); 
} 
+1

이 솔루션은 대용량 CSV 파일에서 매우 비효율적 일 수있는 O (N * M) 복잡도를가집니다. 다른 답에 요약 된 해법은 복잡도 O (N + M)을 갖는다. –

1

하나의 일반적인 방법은 하나 개의 파일에서의 각 행에 대한 해시 코드를 계산하는 것이다 (바람직하게는 하나의 작은). 그런 다음 전체 파일을 해시 테이블에 저장합니다. 이것은 작은 파일의 색인이됩니다.

그런 다음 큰 파일을 탐색하십시오. 각 행에 대해 해시를 계산합니다. 그런 다음 색인을 살펴보십시오. 거기에 그러한 해시 코드가 없다면,이 행은 차이점입니다. 그렇지 않은 경우 해시 코드가있는 경우 (여러 행에 동일한 해시가있을 수 있음) 해시 테이블의 모든 충돌 행과 원본 행의 전체 비교를 수행하고 중복이 있는지 확인합니다.

이제 복제본이 없으면 소스 파일의 행이 다시 고유하여 출력으로 푸시됩니다.

중복이있는 경우 해시 테이블에서 복제본을 제거하고 입력 행을 건너 뛰고 싶을 수 있습니다. 즉, 두 파일의 두 행이 동일하게 감지되어 서로 취소됩니다.

큰 파일을 보았을 때 해시 테이블의 나머지 행을 어떻게 처리할지 결정해야합니다. 다른 파일에 존재하지 않는 행이기 때문에 모든 파일을 출력으로 보내기를 원할 수도 있습니다. 이제

나는 의사를 개설하려고합니다 :

dict = new dictionary<code, list<row>> 

-- Indexing phase 
foreach row in file1 
    code = hash(row) 
    if dict.contains(code) then 
     dict[hash].add(row) 
    else 
     dict[hash] = new list(row) 

-- Comparison phase 
foreach row in file2 
    code = hash(row) 
    bool unique = true 
    if dict.contains(code) then 
     foreach indexedRow in dict[code] 
      if indexedRow is the same as row then 
       begin 
        unique = false 
        remove indexedRow from dict[code] 
       end 
    if unique then 
     push row to output 

-- Finalization phase 
foreach row in dict 
    push row to output 
이 솔루션의

최고의 품질의 실행 시간 복잡도는 M과 N 행의 수는 O (M + N)는, 때문이다 각 파일. 단점은 인덱스에 O (min (M, N)) 메모리가 필요하다는 것입니다.

관련 문제