งูหลาม 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]ที่เป็น isomorphic Xคำนำหน้าของ
ทำงานจากซ้ายไปขวาเรากำหนดดัชนีแต่ละตัวให้เท่ากับระยะทางไปยังเหตุการณ์ล่าสุดที่เกิดขึ้นล่าสุดของตัวละครนั้นหรือหากไม่มีเหตุการณ์ก่อนหน้านี้เราจะใช้ความยาวของคำนำหน้าสตริงปัจจุบัน ตัวอย่างเช่น:
MISSISSIPPI
12313213913
ในการทดสอบว่าอักขระสองตัวตรงกันหรือไม่เราเปรียบเทียบดัชนีปรับอย่างเหมาะสมสำหรับดัชนีที่มากกว่าความยาวของสตริงปัจจุบัน (ย่อย)
อัลกอริทึม KMP จะง่ายขึ้นเล็กน้อยเนื่องจากเราไม่สามารถจับคู่อักขระตัวแรกไม่ตรงกัน
โปรแกรมนี้จะส่งออกการแข่งขันครั้งแรกถ้ามีอยู่ ฉันใช้ข้อผิดพลาดรันไทม์เพื่อออกในกรณีที่มีการแข่งขัน แต่รหัสสามารถแก้ไขได้อย่างง่ายดายเพื่อออกอย่างหมดจดในราคาไบต์บาง
หมายเหตุ:สำหรับการคำนวณดัชนีเราสามารถใช้str.rfind(ตรงข้ามกับวิธีก่อนหน้าของฉันโดยใช้พจนานุกรม) และยังคงมีความซับซ้อนเชิงเส้นโดยสมมติว่าstr.rfindเริ่มค้นหาจากตอนท้าย เราไม่จำเป็นต้องข้ามส่วนเดียวกันของสตริงสองครั้งดังนั้นจึงมีการเปรียบเทียบขอบเขต (ขนาดของตัวอักษร) * (ขนาดของสตริง)
เนื่องจากรหัสมีความสับสนในการตีกอล์ฟต่อไปนี้เป็นวิธีแก้ปัญหาก่อนหน้า (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คำสั่งกำหนดดัชนีและไม่ initialisations ตัวแปรบาง กระบวนการลูปแรกXสำหรับค่าถอยกลับและลูปที่สองทำการค้นหาสตริง
อัปเดต:ต่อไปนี้เป็นเวอร์ชันที่ออกอย่างหมดจดในราคาหนึ่งไบต์:
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