Geriye dönük bir ilişki


10

İki ASCII dizesi verilen Ave Bdizeler üretecek A've B'ortak alt dizelerin yerine ters çevrildiği bir program veya işlev yazın . Bulma süreci A'aşağıdaki gibidir:

  1. A' başlangıçta boştur.
  2. İlk karakteri ise Aiçindedir B, en uzun önek bulmak Abir alt dize olan B. Bu öneki kaldırın Ave tersine dönmesini ekleyin A'.
  3. Aksi takdirde, bu ilk karakteri karakterden kaldırın Ave grubuna ekleyin A'.
  4. ABoş olana kadar 2-3 . Adımları tekrarlayın .

Bulma B'da benzer şekilde yapılır.

Misal

Dizeleri ele alalım A = "abc bab"ve B = "abdabc". Çünkü A'olan budur:

  • A = "abc bab": İlk karakter "a"B'de ve B'de bulunan A'nın en uzun ön eki "abc". Bu öneki A'dan kaldırır ve tersini "cba"A ' ya ekleriz .
  • A = " bab": İlk karakter " "B'de değildir, bu yüzden bu karakteri A'dan kaldırır ve A 'ya ekleriz.
  • A = "bab": İlk karakter "b"B'de ve B'de bulunan A'nın en uzun ön eki "b". Bu öneki A'dan kaldırır ve tersine (hala "b") A'ya ekleriz .
  • A = "ab": İlk karakter "a"B'de ve B'de bulunan A'nın en uzun ön eki "ab". Bu öneki A'dan kaldırır ve tersini "ba"A ' ya ekleriz .
  • A = "": A boş, bu yüzden duruyoruz.

Böylece anlıyoruz A' = "cba" + " " + "b" + "ba" = "cba bba". B 'için süreç benzerdir:

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öylece anlıyoruz B' = "ba" + "d" + "cba" = "badcba".

Son olarak, iki dizeyi döndürüyoruz, yani

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

Test senaryoları

"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"

Bayt cinsinden en kısa kod kazanır.


Tüm girdilerin küçük harfli ASCII olduğunu düşünüyor muyuz? Tam çıktının "cba bba", "badcba"tırnak işaretleri ve virgül içermeye benzemesi bekleniyor mu?
AdmBorkBork

@TimmyD Tam giriş / çıkış formatı seçiminizdir. Girişin küçük harf ASCII olduğunu varsayamazsınız - yazdırılabilir ASCII olabilir.
orlp

Boş dize yasal bir girdi mi?
MtnViewMark

@MtnViewMark Evet.
orlp

Yanıtlar:



2

Haskell'in 120 111 bayt

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

Test çalıştırmaları:

λ: "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 bayt

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).

Örnek: a("birds flying high","whistling high nerds",X,Y).çıktılar

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

Bir şekilde, yolu dizeleri ile uğraşırken Prolog olduğunu ayrıntılı göstermek çok gider çok uzun bir çözümdür. Dizeleri ( `birds flying high`) yerine kod dizileri ( ) kullanarak bu şeyi kısaltmak mümkün olabilir "birds flying high".


1

Python 2.7, 169 156 152 141 Bayt

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

Fonksiyon m2 dizgeyi girdi olarak alır. bFonksiyonu, özelliklere göre gerçek işleme yapan iki kez çağırır .
Burada demo .
Test ediliyor -

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

ÇIKTILAR:

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

PS: kullanarak çözüm için orlp sayesinde next()


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

Ayrıca while len(A)>0sadece ile değiştirebilirsiniz while A. Benzer şekilde if len(p)>0olur if p.
orlp

if len(p)olabilir if p. (Zaten yukarıda söyledim, ama kaçırdın.)
mbomb007

@ mbomb007 Düzgün okumadım. Sadece değiştirilir len(p)>0için len(p). Bunun için teşekkürler :)
Kamehameha

Hatta daha kısa: 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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.