LoginSignup
0
0

AtCoder ABC 322 B - Prefix and Suffix: Z-algo, ロリハ, 編集距離, Python rfindなどで解く

Posted at

文字列に慣れるためにいろいろな方法で解きます。

  • 1: find, スライスで文字列比較
  • 2: suffix検出をrfind
  • 3: suffix検出をfindの開始位置指定
  • 4: suffix検出をひっくり返してprefix判定にする
  • 5: Z algorithm
  • 6: ローリングハッシュ
  • 7: 編集距離(レーベンシュタイン距離)

1: find, スライスで文字列比較

Pythonのfind()は検出された最初の位置を返すので0か判定すればよいです。
Pythonのstr()[-k:]は最後のk文字を取り出します。
答えの表示はboolでif分岐が妥当ですがじっと眺めると0b11をxorすればよいです。

n, m = map(int, input().split())
s, t = input(), input()
ans = 3
if t.find(s) == 0: ans ^= 0b10
if t[-n:] == s: ans ^= 0b01
print(ans)

2: suffix検出をrfind

Pythonにはrfindがあり検出された最後の位置を返す関数があります。

if t.find(s) == 0: ans ^= 0b10
if t.rfind(s) == m-n: ans ^= 0b01

3: suffix検出をfindの開始位置指定

Pythonのfindはfind(sub[, start[, end]])startで開始位置を指定できます。

if t.find(s) == 0: ans ^= 0b10
if t.find(s, m-n) != -1: ans ^= 0b01

4: suffix検出をひっくり返してprefix判定にする

sがtのsuffixであるとは、sとtをひっくり返した状態でsがtのprefixであるか?と同値です。
Pythonではstr[::-1]で文字列をひっくり返せます。

if t.find(s) == 0: ans ^= 0b10
s = s[::-1]
t = t[::-1]
if t.find(s) == 0: ans ^= 0b01

5: Z algorithm

Z algorithmは与えられた文字列におけるすべての位置$i$からの最長共通接頭辞長を$O(N)$で求められます。Z algorithmの典型としては文字列abcababcがあるとき、出現しない文字列_などを用いてabc_ababcをつくりこれを入力とします。

z = zAlgorithm(s + "_" + t)
# t開始からの最長共通接頭辞長がn以上ならprefix
if z.res[n+1] >= n: ans ^= 0b10
# 最後からn文字前の最長共通接頭辞長がn以上ならsuffix
if z.res[n+1+m-n] >= n: ans ^= 0b01

6: ローリングハッシュ

ローリングハッシュはO(N)の事前計算をしておくことである区間の文字列のハッシュをO(1)で求めることが出来ます。

rhs = rollingHash61(s)
rht = rollingHash61(t)
# それぞれ、[0,n)のhashが一緒ならprefix
if rhs.hash(0, n) == rht.hash(0, n): ans ^= 0b10
# sの[0,n)とtの[m-n, m)のhashが一緒ならsuffix
if rhs.hash(0, n) == rht.hash(m-n, m): ans ^= 0b01

7: 編集距離(レーベンシュタイン距離)

二つの文字列を字の挿入/削除/置換で一方を他方に変形するための最小手順回数です。
prefixはdistance(s, t) == m-nでいいように思えますが、abc, aabcのとき距離1になってしまうので"_"などの使われない文字をダミーで入れてやります。

if levenshtein_distance(s + "_"*(m-n), t) == m-n: ans ^= 0b10
if levenshtein_distance("_"*(m-n) + s, t) == m - n: ans ^= 0b01

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0