ความสัมพันธ์ย้อนหลัง


10

เขียนโปรแกรมหรือฟังก์ชั่นที่ได้รับสตริง ASCII สองสายAและBจะสร้างสตริงA'และB'ตำแหน่งที่สตริงย่อยทั่วไปกลับด้าน กระบวนการในการค้นหาA'มีดังนี้:

  1. A' ตอนแรกว่างเปล่า
  2. ถ้าตัวอักษรตัวแรกของAที่อยู่ในBการค้นหาคำนำหน้ายาวที่สุดของซึ่งเป็นย่อยของA Bลบคำนำหน้านี้จากและเพิ่มการโอนกลับไปยังAA'
  3. มิฉะนั้นลบตัวอักษรตัวแรกนี้จากและเพิ่มเข้าไปAA'
  4. ทำซ้ำขั้นตอนที่ 2-3 จนกระทั่งAว่างเปล่า

การค้นหาB'จะทำในทำนองเดียวกัน

ตัวอย่าง

ลองพิจารณาสตริงและA = "abc bab" B = "abdabc"สำหรับA'นี่คือสิ่งที่เกิดขึ้น:

  • A = "abc bab": ตัวอักษรตัวแรก"a"ที่อยู่ในบีและคำนำหน้ายาวที่สุดของที่พบใน B "abc"คือ เราลบคำนำหน้านี้ออกจาก A และเพิ่มการกลับรายการ"cba"เป็น A '
  • A = " bab": อักขระตัวแรก" "ไม่ได้อยู่ใน B ดังนั้นเราจึงลบตัวละครนี้ออกจาก A และเพิ่มลงใน A '
  • A = "bab": ตัวอักษรตัวแรก"b"ที่อยู่ในบีและคำนำหน้ายาวที่สุดของที่พบใน B "b"คือ เรานำคำนำหน้านี้ออกจาก A และเพิ่มการกลับรายการ (ซึ่งยังคงอยู่"b") ใน A '
  • A = "ab": ตัวอักษรตัวแรก"a"ที่อยู่ในบีและคำนำหน้ายาวที่สุดของที่พบใน B "ab"คือ เราลบคำนำหน้านี้ออกจาก A และเพิ่มการกลับรายการ"ba"เป็น A '
  • A = "": A ว่างเปล่าดังนั้นเราหยุด

A' = "cba" + " " + "b" + "ba" = "cba bba"ดังนั้นเราจึงได้รับ สำหรับ B 'กระบวนการจะคล้ายกัน:

B = "abdabc"  ->  "a" in A, remove prefix "ab"
B = "dabc"    ->  "d" not in A, remove "d"
B = "abc"     ->  "a" in A, remove prefix "abc"

B' = "ba" + "d" + "cba" = "badcba"ดังนั้นเราจึงได้รับ

ในที่สุดเรากลับสองสตริงคือ

(A', B') = ("cba bba", "badcba")

กรณีทดสอบ

"abc bab", "abdabc" -> "cba bba", "badcba"
"abcde", "abcd bcde" -> "dcbae", "dcba edcb"
"hello test", "test banana" -> "hello tset", "tset banana"
"birds flying high", "whistling high nerds" -> "bisdr flyhgih gni", "wihstlhgih gni nesdr"

รหัสที่สั้นที่สุดในหน่วยไบต์ชนะ


เราสมมติว่าอินพุตทั้งหมดเป็นตัวพิมพ์เล็ก ASCII หรือไม่ คาดว่าผลลัพธ์ที่แน่นอนจะคล้ายกับ"cba bba", "badcba"คำพูดและเครื่องหมายจุลภาค?
AdmBorkBork

@ TimmyD รูปแบบอินพุต / เอาต์พุตที่แน่นอนคือตัวเลือกของคุณ คุณไม่สามารถสันนิษฐานว่าอินพุตเป็นตัวพิมพ์เล็ก ASCII - อาจเป็น ASCII ที่พิมพ์ได้
orlp

สตริงว่างเปล่าเป็นอินพุตตามกฎหมายหรือไม่?
MtnViewMark

@MtnViewMark ใช่
orlp

คำตอบ:



2

Haskell, 120 111 ไบต์

import Data.List
a&b=(a#b,b#a)
[]#_=[]
(a:y)#b=[a]%y where p%(i:w)|reverse(i:p)`isInfixOf`b=(i:p)%w;p%x=p++x#b

ทดสอบการทำงาน:

λ: "abc bab"&"abdabc"
("cba bba","badcba")

λ: "abcde"&"abcd bcde"
("dcbae","dcba edcb")

λ: "hello test"&"test banana"
("hello tset","tset banana")

λ: "birds flying high"&"whistling high nerds"
("bisdr flyhgih gni","wihstlhgih gni nesdr")

1

SWI-Prolog ขนาด 312 ไบต์

a(A,B,X,Y):-b(A,B,"",X),b(B,A,"",Y).
b(A,B,R,Z):-A="",R=Z;sub_string(A,0,1,_,C),(sub_string(B,_,1,_,C),(string_length(A,J),I is J-1,between(0,I,K),L is J-K,sub_string(A,0,L,_,S),sub_string(B,_,L,_,S),string_codes(S,E),reverse(E,F),string_codes(Y,F));S=C,Y=C),string_concat(S,V,A),string_concat(R,Y,X),b(V,B,X,Z).

ตัวอย่าง: a("birds flying high","whistling high nerds",X,Y).ผลลัพธ์

X = "bisdr flyhgih gni",
Y = "wihstlhgih gni nesdr" .

วิธีการแก้ปัญหาที่ยาวเกินไปซึ่งจะแสดงให้เห็นว่า Prolog verbose ทำงานอย่างไรเมื่อจัดการกับสตริง อาจเป็นไปได้ที่จะย่อให้สั้นลงโดยใช้รหัสอาร์เรย์ ( `birds flying high`) แทนสตริง ( "birds flying high")


1

Python 2.7 169 156 152 141 ไบต์

m=lambda A,B:(b(A,B),b(B,A))
def b(A,B,C=''):
 while A:j=next((j for j in range(len(A),0,-1)if A[:j]in B),1);C+=A[:j][::-1];A=A[j:]
 return C

ฟังก์ชั่นmใช้ 2 สตริงเป็นอินพุตมันเรียกใช้bฟังก์ชันสองครั้งซึ่งทำการประมวลผลจริงตามข้อมูลจำเพาะ สาธิตที่นี่

ทดสอบมัน -

l=[("abc bab", "abdabc"),
("abcde", "abcd bcde"),
("hello test", "test banana"),
("birds flying high", "whistling high nerds")]
for e in l:
    print m(*e)

เอาท์พุท:

('cba bba', 'badcba')
('dcbae', 'dcba edcb')
('hello tset', 'tset banana')
('bisdr flyhgih gni', 'wihstlhgih gni nesdr')

PS: ขอบคุณ orlp สำหรับการแก้ปัญหาโดยใช้ next()


m=lambda A,B:(b(A,B),b(B,A))
orlp

นอกจากนี้คุณสามารถแทนที่มีเพียงwhile len(A)>0 while Aในทำนองเดียวกันจะกลายเป็นif len(p)>0 if p
orlp

if len(p)if pนอกจากนี้ยังสามารถ (พูดแล้วข้างต้น แต่คุณพลาด)
mbomb007

@ mbomb007 อ่านไม่ถูกต้อง เพียงแค่เปลี่ยนไปlen(p)>0 len(p)ขอบคุณสำหรับ :) :)
Kamehameha

while A:j=next((j for j in range(len(A),0,-1)if A[:j]in B),1);C+=A[:j][::-1];A=A[j:]แม้สั้น:
orlp
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.