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 với 0 trạng thái thoát)
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!'
Thuật toán là một biến thể của KMP, sử dụng thử nghiệm dựa trên chỉ mục để khớp ký tự. Ý tưởng cơ bản là nếu chúng ta có một sự không phù hợp ở vị trí X[i]thì chúng ta có thể quay trở lại vị trí có thể tiếp theo cho một trận đấu theo hậu tố dài nhất của X[:i]nó là đẳng cấu với tiền tố X.
Làm việc từ trái sang phải, chúng tôi gán cho mỗi ký tự một chỉ số bằng khoảng cách đến lần xuất hiện gần đây nhất của ký tự đó hoặc nếu không có lần xuất hiện trước thì chúng tôi lấy độ dài của tiền tố chuỗi hiện tại. Ví dụ:
MISSISSIPPI
12313213913
Để kiểm tra xem hai ký tự có khớp nhau hay không, chúng tôi so sánh các chỉ số, điều chỉnh phù hợp cho các chỉ số lớn hơn độ dài của chuỗi (phụ) hiện tại.
Thuật toán KMP trở nên đơn giản hơn một chút vì chúng ta không thể có được sự không phù hợp trên ký tự đầu tiên.
Chương trình này xuất kết quả khớp đầu tiên nếu có. Tôi sử dụng một lỗi thời gian chạy để thoát trong trường hợp khớp, nhưng mã có thể dễ dàng sửa đổi để thoát sạch với chi phí của một số byte.
Lưu ý: Đối với các chỉ số điện toán, chúng ta có thể sử dụng str.rfind(trái ngược với cách tiếp cận trước đây của tôi bằng từ điển) và vẫn có độ phức tạp tuyến tính, giả sử rằngstr.rfind bắt đầu tìm kiếm từ cuối (có vẻ là lựa chọn thực hiện lành mạnh duy nhất) - cho mỗi ký tự trong bảng chữ cái , chúng ta không bao giờ phải đi qua cùng một phần của chuỗi hai lần, do đó, có một giới hạn trên của (kích thước của bảng chữ cái) * (kích thước của chuỗi) so sánh.
Vì mã đã bị xáo trộn khá nhiều trong quá trình chơi gôn, đây là một giải pháp sớm hơn (293 byte) dễ đọc hơn một chút:
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!'
Các exét nghiệm chức năng tương đương của nhân vật. Câu execlệnh gán các chỉ số và thực hiện một số khởi tạo biến. Vòng lặp đầu tiên xử lý Xcác giá trị dự phòng và vòng lặp thứ hai thực hiện tìm kiếm chuỗi.
Cập nhật: Đây là phiên bản thoát hoàn toàn, với giá một byte:
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