2016-03-24 7 views
1

2つの文字列を比較し、文字列の1つをリストに追加しようとしています。私の言葉のセットが90kを超えているので、これを行う最速の方法は何ですか?これを行うにはしばしば時間がかかりますか?2つの文字列が大きな文字列の1文字で異なるかどうかを判断する最速の方法

EDIT:下のコードのcomparison_wordの1つが変更されません。

EDIT2:言葉は同じ長さでなければなりません

これは私の現在のコードです:

for word in set_of_words: 
     amount = 0 
     if len(word) == len(comparison_word): 
      for i in range(len(word)): 
       if comparison_word[i] != word[i]: 
        amount += 1 
      if amount == 1: 
       list_of_words.append(word) 
    return list_of_words 
+0

'foo'と' fo'についてはどうですか? –

+0

「言葉のセット」はどうやって変わるのですか? –

答えて

1

アイデアが行われている作業の量を減らすことです。

n_comparison_word = len(comparison_word) 
for word in set_of_words: 
    amount = 0 
    n_word = len(word) 
    if n_word != n_comparison_word: 
     continue 
    for i in range(n_word): 
     if comparison_word[i] != word[i]: 
      amount += 1 
     if amount == 2: 
      break 
    if amount == 1: 
     list_of_words.append(word) 
return list_of_words 

一部注:

  • eはlen(comparison_word)の計算は一度だけ(今まで)計算する必要があります。
  • len(word)の値は1回計算する必要があります(ループの反復ごとに)。
  • amountが値2に達したときに単語を見るのを止めることができます(どんな場合でも、その単語は結果に含まれなくなる可能性があります)。

これは、両方のコードで使用されcontinuebreak文についてthis part of the Python documentationを読む価値があってもよいです。

+0

私は彼らがすべての言葉をお互いに比較しようとしていると思います。だから私は最初のステップは、各ハッシュがユニークな単語のリストを保持した単語の長さの辞書を作成することであると思います。 –

+0

平均時間が40秒から30秒に短縮されました – sleepless

0

comparison_wordの長さがあまり長くなくても(6文字未満)、set_of_wordsが変更できる場合は、許容可能なすべての単語を計算し、それらをセットに格納してください単にset_of_wordsを繰り返し、word in acceptable_wordsをテストしてください。

ない場合は、ここにあなたのコードに私のテイクがあります:基本的に

for word in set_of_words: 
    different_letter_exists = False 
    length = len(word) 
    if length == len(comparison_word): 
    for i, letter in enumerate(word): 
     if letter != comparison_word[i]: 
      if different_letter_exists: 
       break 
      else: 
       different_letter_exists = True 
    if i == length: 
     list_of_words.append(word) 

:あなたは別の文字に遭遇したら、すべての単語のために、different_letter_existsがTrueに設定されています。もう一度それに遭遇すれば、あなたはループから脱出する。 i == lengthの場合にのみ新しい単語が追加されます。これは、enumerateが最後まで届くと発生します。これは、異なる文字が1つだけ存在する場合にのみ発生します。

幸運:)

2

あなたはジッパーがインデックスよりも効率的であるかもしれません:

def almost_equal(set_of_words,comp): 
    ln = len(comp) 
    for word in set_of_words: 
     count = 0 
     if len(word) == ln: 
      for a, b in zip(word, comp): 
       count += a != b 
       if count == 2: 
        break 
      else: 
       yield word 

デモ:

In [5]: list(almost_equal(["foo","bar","foob","foe"],"foa")) 
Out[5]: ['foo', 'foe'] 
+0

[this solution](http://stackoverflow.com/a/36208085/3566755)とともに、平均時間が40秒から28秒に短縮されました – sleepless

+0

リストへのアクセスは非常にわずかに速いかもしれません –

0

以下が約25で61Kの単語の私の辞書を検索msec。

import re 

def search(word, text): 
    ws = [r'\b{}[^{}]{}\b'.format(w[:i],w[i],w[i+1:]) for i in range(len(word))] 

    for mo in re.finditer('|'.join(ws), text): 
     yield mo.group() 

with open("/12dicts/5desk.txt") as f: 
    text = f.read() 

for hit in search('zealoos', text): 
    print(hit)       #prints zealous 

文字列のリストは、ファイル内の1行に1つの文字列、1つの長い文字列としてそれを読んで、マッチのために文字列を検索するために正規表現を使用していることを仮定。 - C-速度で

\b[^w]hat\b|\bw[^h]at\b|\bwh[^a]t\b|\bwha[^t]\b 

そして、すべての単語をスキャンし、すべてのニアミスを見つける:

search()は「何とこのような正規表現に変換しますのような言葉を取ります。

関連する問題