2

最長の共通部分列を見つけるアルゴリズムを設計しました。これらは手順です:

  • 最初の文字列の最初の文字を選択します。

  • 2 番目の文字列でそれを探し、見つかった場合は、その文字を に追加し、 common_subsequenceその位置を に保存します。そうでない場合は、 の長さと の長indexさを比較し、 大きい場合は、その値を に代入します。common_subsequencelcslcs

  • 最初の文字列に戻り、次の文字を選択して、前の手順をもう一度繰り返しますが、今度はindex番目の文字から検索を開始します

  • 選択する最初の文字列に文字がなくなるまで、このプロセスを繰り返します。最後に、の値はlcs最長共通サブシーケンスです。

これは例です:
</p>

X=A, B, C, B, D, A, B‬‬  
‫‪Y=B, D, C, A, B, A‬‬ 

最初の文字列を選択Aします。で
を探します。 2 番目の文字列にがあるので、それを に追加します。 最初の文字列に戻り、次の文字を選択します。今度は の位置から 2 番目の文字列を探します。 の後にあるので、 に B を追加します。 次に、最初の文字列の次の文字を選択します。2 番目の文字列には次の toはありません。したがって、その長さが の長さより大きいため、common_subsequence の値を に割り当てます。最初の文字列の終わりに到達するまで、前の手順を繰り返します。結局の値はAY
Acommon_subsequence
BBA
BAcommon_subsequence
CCBlcslcslcs最長共通部分列です。

このアルゴリズムの複雑さは theta(n*m) です。ここに私の実装があります:

最初のアルゴリズム:

import time
def lcs(xstr, ystr):
    if not (xstr and ystr): return # if string is empty
    lcs = [''] #  longest common subsequence
    lcslen = 0 # length of longest common subsequence so far
    for i in xrange(len(xstr)):
        cs = '' # common subsequence
        start = 0 # start position in ystr
        for item in xstr[i:]:
            index = ystr.find(item, start) # position at the common letter
            if index != -1: # if common letter has found
                cs += item # add common letter to the cs
                start = index + 1
            if index == len(ystr) - 1: break # if reached end of the ystr
        # update lcs and lcslen if found better cs
        if len(cs) > lcslen: lcs, lcslen = [cs], len(cs) 
        elif len(cs) == lcslen: lcs.append(cs)
    return lcs

file1 = open('/home/saji/file1')
file2 = open('/home/saji/file2')
xstr = file1.read()
ystr = file2.read()

start = time.time()
lcss = lcs(xstr, ystr)
elapsed = (time.time() - start)
print elapsed

ハッシュ テーブルを使用した同じアルゴリズム:

import time
from collections import defaultdict
def lcs(xstr, ystr):
    if not (xstr and ystr): return # if strings are empty
    lcs = [''] #  longest common subsequence
    lcslen = 0 # length of longest common subsequence so far
    location = defaultdict(list) # keeps track of items in the ystr
    i = 0
    for k in ystr:
        location[k].append(i)
        i += 1
    for i in xrange(len(xstr)):
        cs = '' # common subsequence
        index = -1
        reached_index = defaultdict(int)
        for item in xstr[i:]:
            for new_index in location[item][reached_index[item]:]:
                reached_index[item] += 1
                if index < new_index:
                    cs += item # add item to the cs
                    index = new_index
                    break
            if index == len(ystr) - 1: break # if reached end of the ystr
        # update lcs and lcslen if found better cs
        if len(cs) > lcslen: lcs, lcslen = [cs], len(cs) 
        elif len(cs) == lcslen: lcs.append(cs)
    return lcs

file1 = open('/home/saji/file1')
file2 = open('/home/saji/file2')
xstr = file1.read()
ystr = file2.read()

start = time.time()
lcss = lcs(xstr, ystr)
elapsed = (time.time() - start)
print elapsed
4

2 に答える 2

10

教授が独自の LCS アルゴリズムを発明するように求めている場合は、それで終わりです。あなたのアルゴリズムはこれまでに作成された中で最も最適なものではありませんが、適切な複雑さのクラスにあり、それを明確に理解しており、実装をインターネットからコピーしていないことは明らかです。アルゴリズムを擁護する準備をしたり、代替案について話し合ったりする必要があるかもしれません。私があなたの教授だったら、次の場合に A を付けます。

  • あなたはそのプログラムを提出しました。
  • O(N) または O(N log M) の代替案が存在しない理由を説明できました。
  • より良い下限(または大幅に低い定数など) を持つ可能性のある他のアルゴリズムや、時間と空間のトレードオフなどについて、その結果を知らなくても、合理的な議論に参加することができました。事前の話し合い。

一方、教授が、よく知られたアルゴリズムの 1 つを選択して独自の実装を作成するように求めている場合は、標準の LP アルゴリズムを使用することをお勧めします。これが標準的なアルゴリズムであることには理由があります。理解するまでは、このアルゴリズムを読み進めてください。(試験に出なくても、教授に感銘を与えるためだけでなく、学ぶためにこのクラスを受講していますよね?)

ウィキペディアには、基本的な実装の疑似コードと、一般的な最適化に関する英語の説明があります。そのページの内容に基づいて独自の Python コードを作成することは、特にコードが何をしているのか、その理由、理由を理解していることを示すことができれば、剽窃や些細な移植とはみなされないと確信しています。それは良いアルゴリズムです。さらに、Python で記述しているため、この記事で説明した方法よりもはるかに優れたメモ化方法を備えているため、その仕組みを理解すれば、実際のコードは Wikipedia で提供されているものよりも大幅に優れているはずです。

いずれにせよ、コメントで提案したように、Bergroth、Hakonen、および Raita による最長共通サブシーケンス アルゴリズムの調査を読み、同様の論文をオンラインで検索します。

于 2013-01-01T00:45:27.143 に答える
-4
maxLength = 0
foundString = ""
for start in xrange(len(str1)-1):
     for end in xrange(start+1, len(str1)):
        str1Temp = str1[start:end]   
        maxLengthTemp = len(str1Temp)
        if(str2.find(str1Temp)):
             if(maxLengthTemp>maxLength):
                 maxLength = maxLengthTemp
                 foundString = str1Temp

print maxLength
print foundString
于 2012-12-31T23:41:11.263 に答える