Зворотні відносини


10

Напишіть програму або функцію, яка, з урахуванням двох рядків ASCII Aі B, буде створювати рядки A'і B'там, де загальні підрядки повернені на їх місце. Процес пошуку A'такий:

  1. A' спочатку порожній.
  2. Якщо перший символ Aу B, знайдіть найдовший префікс Aякого є підрядком B. Видаліть цей префікс Aі додайте його сторнування до A'.
  3. В іншому випадку видаліть цього першого символу Aта додайте його до A'.
  4. Повторіть кроки 2-3, поки Aне заповниться.

Пошук B'робиться аналогічно.

Приклад

Розглянемо рядки A = "abc bab"і B = "abdabc". Бо A'ось що відбувається:

  • A = "abc bab": Перший символ "a"знаходиться в B, а найдовший префікс A, знайдений у B, - це "abc". Видаляємо цей префікс з A і додаємо його сторнування "cba"до A '.
  • A = " bab": Перший символ " "не в B, тому ми видаляємо цей символ з A і додаємо його до A '.
  • A = "bab": Перший символ "b"знаходиться в B, а найдовший префікс A, знайдений у B, - це "b". Видаляємо цей префікс з A і додаємо його сторнування (яке досі "b") до A '.
  • A = "ab": Перший символ "a"знаходиться в B, а найдовший префікс A, знайдений у B, - це "ab". Видаляємо цей префікс з A і додаємо його сторнування "ba"до 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" .

Шлях, шлях занадто довго рішення , яке йде занадто показати , як багатослівний Пролог при роботі з рядками. Можна скоротити цю річ, використовуючи кодові масиви ( `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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.