2016-06-30 34 views
0

行ごとに2つのcsv(巨大ファイル)を比較し、差分行を別々のファイルに書き込む必要があります。 1つのファイル内の行は、2番目のファイルの任意の場所に存在できます。私は行全体を比較する必要があります。 ポインタはありますか?間に合わせ2つの大きな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

一つの一般的なアプローチは、一つのファイル内の行の各々に対してハッシュコードを計算することである(好ましくは、小さい方)。次に、ファイル全体をハッシュテーブルに入れます。これは小さなファイルのインデックスになります。

その後、大きなファイルを歩きます。各行について、そのハッシュを計算します。次に索引を調べます。そのようなハッシュコードがない場合、この行は違いです。そうでない場合、そのようなハッシュコードが存在する場合(複数の行に同じハッシュが存在する可能性があります)、ハッシュテーブル内のすべての衝突する行とソース行の比較全体を実行し、重複があるかどうかを確認します。

ここで重複がない場合、ソースファイルの行は再び一意であり、出力にプッシュします。

重複がある場合は、その重複をハッシュテーブルから削除し、入力行をスキップすることができます。つまり、2つのファイルの2つの行が等しいと検出され、互いにキャンセルされます。

大きなファイルを歩き終わったら、ハッシュテーブルの残りの行をどうするかを決定する必要があります。他のファイルに存在しなかった行であるため、それらのすべてを出力にプッシュすることもできます。

今、私は擬似コードの概要を説明してみましょう:このソリューションの

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))のメモリーが必要だということです。

関連する問題