Drkcore

10 12 2007 perl MAWP Python Tweet

PythonでBoyer-Moore法

ProductName Mastering Algorithms With Perl
Jon Orwant
Oreilly & Associates Inc / 2553円 ( 1999-07 )


perlは写経でいまいち理解度があやしいため、pythonでBoyer-Moore法を。パターンとの不一致の場合には何文字スキップできるか、一致した場合に何文字スキップできるかのテーブルを最初に作っておいて、スキップ幅の大きいほうでスキップしながらパターンマッチを進めていく。

def boyer_moore_bad_character (P):
   m = len(P)
   bc = [m] * 256
   j = m
   for char in list(P):
       bc[ord(char)] = j - 1
       j -= 1

   return m, bc

def boyer_moore_good_suffix (m,P):
   j = m + 1
   gs = [0] * j
   k = [0] * j
   k[m] = j
   for i in reversed(range(1,j)):
       while j <= m and P[i-1] != P[j-1]:
           if gs[j] == 0:
               gs[j] = j - i
           j = k[j]
       j -= 1
       k[i-1] = j

   kn = k[0]
   for j in range(m+1):
       if gs[j] == 0: gs[j] = kn
       if j == kn: kn = k[kn]

   gs.pop(0)
   return gs

def boyer_moore (T,P):
    (m,bc) = boyer_moore_bad_character(P)
    gs    = boyer_moore_good_suffix(m,P)

    (i, last_i, first_j) = (0, len(T)-m, m-1)

    for i in range(last_i+1):
        j = first_j
        while j >= 0 and T[i+j] == P[j]:
            j -= 1
        if j < 0:
            return i
        else:
            bcn = bc[ord(T[i+j])] - m + j + 1
            gsn = gs[j]
            i += bcn if bcn > gsn else gsn
    return -1

if __name__ == '__main__':
    print boyer_moore("perlpypythonruby","python")
  • pythonはコードの見通しがよいですな
  • perlと違ってsubstrとかやらなくてもいいので見通しがよい
  • perlのshiftがpop(0)なのがあれ。先頭をpopするってのが。
  • perlだと$a[5]=5とやれるけど、pythonはそれ以前の要素が自動的ににundefで埋まらない

for文でカウンタ変数使いたかったのでrangeをつかったけどPython流はどうやるのがよろしいんだろうか、、、カウンタ変数減算するのにfor i in reversed(range(1,j))だしな。

About

  • もう5年目(wishlistありマス♡)
  • 最近はPythonとDeepLearning
  • 日本酒自粛中
  • ドラムンベースからミニマルまで
  • ポケモンGOゆるめ

Tag

Python Deep Learning javascript chemoinformatics Emacs sake and more...

Ad

© kzfm 2003-2021