Палиндром (домашнее задание)

Я пытался написать программу Prolog, используя списки. Тем не менее, я должен использовать списки различий и вывод должен быть:

I-й элемент списка совпадает с (n-i+1)-ым элементом списка, а n - это длина списка. Например, [a,X,c,b,Y] должен дать X = b а также Y = a, Я не смог найти подобный пример палиндрома в других вопросах.

До сих пор я реализовал:

% length of the list 
len([], 0).
len([H|T], B) :-
   len(T, NT),
   B is NT + 1.

% return the ith element of the list 
match([H|_], 0, H) :-
   !.
match([_|T], N, H) :-
   N > 0,
   N1 is N-1,
   match(T, N1, H).

Однако я не смог завершить. Пожалуйста, помогите мне!

1 ответ

Решение

Используйте определенные грамматики предложения!

DCG, основная функция Prolog, упрощает использование списков различий, позволяя вам писать краткий и эффективный код без особых усилий!

Хотите узнать больше? Просто следуйте точкам:

Без дальнейших церемоний, давайте перейдем к коду:

палиндром -> [].
палиндром -> [_].
палиндром -> [X], палиндром, [X].

В качестве альтернативы, мы могли бы также использовать следующее более компактное определение:
палиндром -> [] | [_] | [X], палиндром, [X].

Готово. Давайте запустим несколько запросов! Сначала запрос ОП дал:

?- phrase(palindrome, [a,X,c,b,Y]).
   X = b, Y = a
;  false.

На немецком языке "кукуруза" называется "маис". Если мы поставим перед собой "сиам" (старое название "Королевство Таиланд"), мы получим восхитительный палиндром:

? - set_prolog_flag (двойные кавычки, символы).
правда.?- фраза (палиндром, "siamm ais").
   правда; ложный.?- фраза (палиндром, "siam ais"). % или ударить один средний символ "м"
   правда% ... для палиндрома нечетной длины; ложный.

Наконец, давайте не будем забывать о самом общем запросе:

?- phrase(palindrome, Xs).
   Xs = []
;  Xs = [_A]
;  Xs = [_A,_A]
;  Xs = [_A,_B,_A]
;  Xs = [_A,_B,_B,_A]
;  Xs = [_A,_B,_C,_B,_A]
...

На уровне пролога мы можем использовать встроенный предикат Пролог listing/1 Чтобы взглянуть на код, в который была переведена DCG - на этом уровне становится очевидным внутреннее использование списков различий:

?- listing(palindrome//0).
palindrome(A, A).
palindrome([_|A], A).
palindrome([C|A], D) :-
    palindrome(A, B),
    B = [C|D].

true.
Другие вопросы по тегам