問題
You are given two strings, A and B. Return whether A can be shifted some number of times to get B.
Eg. A = abcde, B = cdeab should return true because A can be shifted 3 times to the right to get B. A = abc and B= acb should return false.
つまり、2つの文字列が渡されて、それがいくつか右にずらすと2つの文字列が一致するのか、そんなことはできないのかを回答する。
例
A = 'shinbunshi'
B = 'nbunshishi'
--> True #Aを4つ右にずらすとBになりますよね。
A = 'apple'
B = 'plepa'
--> False #AをいくつずらそうともBにはなりません。Aは'eappl','leapp','pleap','pplea'にしかなりません。
解法1
def is_shifted(a, b):
# input strings, strings
# return True or False
if len(a) != len(b):
return False
if a == b:
return True
# checking all index.
for index in range(len(a)):
if a[0] == b[index]:
left_length = len(a) - index
if a[:left_length] == b[-left_length:] and a[left_length:] == b[:-left_length]:
return True
return False
想定している結果を返しますが、もっとスマートな書き方があります。
解法2
def is_shifted(a, b):
# input strings, strings
# return True or False
if len(a) != len(b):
return False
if len(a) == 0:
return True
for s in range(len(a)):
if all(a[(s+i) % len(a)] == b[i] for i in range(len(a))):
return True
return False
回答方針は同じですが、スッキリしましたね。
些細なことですが、解法1では文字列が''の場合を考慮できていませんでした。解法2ではうまく対処できています。
解法2のallの使い方や、a[(s+i) % len(a)]のようにしてIndexError: string index out of rangeのエラーを回避しています。