2017-08-25 4 views
1

私はオンラインで回答を検索しようとしましたが、残念ながら成功しませんでした。したがって、私はここに尋ねています:file1の行がfile2の行のサブセットであるかどうかをテストします。

file1のすべての行がfile2に存在するかどうかを調べようとしています。幸運にも、個々の単語などではなく、行全体を比較することができます。不運にも私はGBファイルを扱っていますので、私が試した基本的な解決法のいくつかが私にメモリエラーを与えました。

現時点では、次のコードは動作しません。いくつかの指針は非常に高く評価されます。

# Checks if all lines in file1 are present in file2 
def isFile1SubsetOfFile2(file1 , file2): 
    file1 = open(file1, "r") 


    for line1 in file1:   
     with open(file2, "r+b") as f: 

      mm=mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) 
      my_str_as_bytes = str.encode(line1) 
      result = mm.find(line1.strip().encode()) 
      print(result) 
      if result == -1: 
       return False 
    return True 

サンプルFILE2:

This is line1. 
This is line2. 
This is line3. 
This is line4. 
This is line5. 
This is line6. 
This is line7. 
This is line8. 
This is line9. 

があれば渡す必要があり、例えばファイル1は:

This is line4. 
This is line5. 

file1は:

This is line4. 
This is line10. 

編集:私はちょうど他の人の利益のために自分のコードの作業バージョンを追加しました。メモリエラーはありませんが、非常に遅いです。

+0

Ickでは、あなたのコードは 'O(m * n)'です。 'O(m log m + n log n) 'でこれを行うことは自明で、' O(m + n) 'でも可能です。 – o11c

+0

Algoの複雑さなどについては、私の頭の上にあります。 – Ali

+0

その後、プログラミングについては*何か他のことを学ぶ前に、アルゴリズムの複雑さとbig-O表記について学んでください。これは重要*。 – o11c

答えて

0

私はそれが動作しない理由はわからないが、私はあなたがそれを解決することができますどのような方法を知っていると思う:

def is_subset_of(file1, file2): 
    with open(file1, 'r') as f1, open(file2, 'r') as f2: 
     for line in f1: 
      line = line.strip() 
      f2.seek(0) # go to the start of f2 
      if line not in (line2.strip() for line2 in f2): 
       return False 
    return True 

これは常に再びスタートを追求することで、複数回の第二のファイルを開く回避それぞれの行について、いつでもメモリ内に2行しか保持しません。それは非常にメモリに優しいはずです。

もう1つの方法(速くなる可能性があります)は、file1file2の両方を並べ替えることです。そうすれば、文字列が最初のファイルの字句よりも小さい場合、行ごとに比較し、他のファイルの次の行に移動することができます。 O(n*log(n))で実行できるO(n**2)の代わりに。しかし、それははるかに複雑で、GBのファイルをソートすることが意味をなさないかどうかは分かりません(あまりにも多くのメモリを使用する可能性があります)。

+0

申し訳ありませんmmap.find()は私にメモリの問題を与えません。マッチングは正しく行われません。 – Ali

+0

ああ、私のコードは正しく動作しましたか? – MSeifert

+0

MSeifert、はい、コードが機能しました。私はあなたに最高票をあげましたが、評判が15未満であるため登録ができません。しかし、あなたのコードは、私が上記に投稿したmmapソリューションよりもはるかに低速です。私は基本的に文字列からストリップ()が欠けていて、マッチングをやっていない理由を教えてくれました。 :)非常 – Ali

0

メモリに収まらないファイルを扱うことは常に困難です。

file1がメモリに収まるが、file2が大きすぎる場合は、ここソリューションです:

# file1 and file2 are open file-like objects 
unseen = set(file1) 
for line in file2: 
    unseen -= {line} # avoid exception from set.remove 
#if unseen is empty, all lines were found in file2 

そうでない場合は、ファイルの少なくとも一つを、あなたが並べ替える必要があります(あるいはCFBSソート)。

関連する問題