Python 2、338 326 323 321 310 306 297 293 290 289 280 279 266 264 259 237 230 229 226 223 222 220 219 217(260 238 231 228 225 223 221 220 218、終了ステータスは0)
exec'''s=raw_input()
S=[M-s.rfind(c,0,M)for M,c in enumerate(s)]
k=0
j=x=%s
while k<=M+x:
if S[k]>j<W[j]or S[k]==W[j]:
k+=1;j+=1;T+=[j]
if j-L>x:print s[k-j:k];z
else:j=T[j]
'''*2%('-1;T=[0];W=S;L=M',0)
print'No!'
このアルゴリズムは、KMPのバリエーションであり、文字一致のインデックスベースのテストを使用しています。基本的な考え方は、位置で不一致が発生した場合、プレフィックスのに同形X[i]でX[:i]ある最長のサフィックスに従って、一致する次の可能な場所にフォールバックできるということですX。
左から右に作業して、各文字にその文字の直前の出現までの距離に等しいインデックスを割り当てるか、以前に出現しない場合は現在の文字列プレフィックスの長さを取得します。例えば:
MISSISSIPPI
12313213913
2つの文字が一致するかどうかをテストするために、インデックスを比較し、現在の(サブ)文字列の長さより大きいインデックスに適切に調整します。
KMPアルゴリズムは、最初の文字で不一致を取得できないため、少し単純化されます。
このプログラムは、最初に一致したものがあればそれを出力します。一致した場合に終了するにはランタイムエラーを使用しますが、コードを簡単に変更して、数バイトのコストできれいに終了することができます。
注:インデックスの計算には、str.rfind(辞書を使用する以前のアプローチとは対照的に)を使用できますstr.rfindが、アルファベットの各文字に対して、最後から検索を開始する(これが唯一の正気の実装選択と思われる)と仮定して、線形の複雑さを保持できます、文字列の同じ部分を2回走査する必要がないため、(アルファベットのサイズ)*(文字列のサイズ)比較の上限があります。
ゴルフの過程でコードがかなり難読化されたため、ここでは少し読みやすい初期の(293バイト)ソリューションを示します。
e=lambda a:a>i<W[i]or a==W[i]
exec('s=raw_input();S=[];p={};M=i=0\nfor c in s:S+=[M-p.get(c,-1)];p[c]=M;M+=1\nW=S;L=M;'*2)[:-9]
T=[0]*L
k=1
while~k+L:
if e(W[k]):i+=1;k+=1;T[k]=i
else:i=T[i]
m=i=0
while m+i<M:
if e(S[m+i]):
if~-L==i:print s[m:m+L];z
i+=1
else:m+=i-T[i];i=T[i]
print'No!'
このe関数は、文字の等価性をテストします。このexecステートメントはインデックスを割り当て、いくつかの変数の初期化を行います。最初のループXはフォールバック値を処理し、2番目のループは文字列検索を行います。
更新:これは、1バイトのコストで正常に終了するバージョンです。
r='No!'
exec'''s=raw_input()
S=[M-s.rfind(c,0,M)for M,c in enumerate(s)]
k=0
j=x=%s
while k<=M+x:
if S[k]>j<W[j]or S[k]==W[j]:
k+=1;j+=1;T+=[j]
if j-L>x:r=k=s[k-j:k]
else:j=T[j]
'''*2%('-1;T=[0];W=S;L=M',0)
print r