Проверить, является ли список палиндромом. Если нет, вставьте элементы, чтобы сделать его палиндромом. (Пролог)
Я написал следующий код, чтобы проверить, является ли оно палиндромом или нет. Я также создал логику для вставки элементов, когда список не является палиндромом
reverse_list(Inputlist, Outputlist) :-
reverse(Inputlist, [], Outputlist).
reverse([], Outputlist, Outputlist).
reverse([Head|Tail], List1, List2) :-
reverse(Tail, [Head|List1], List2).
printList([]).
printList([X|List]) :-
write(X),
write(' '),
printList(List).
palindrome(List1) :-
reverse_list(List1, List2),
compareLists(List1, List1, List2, List2).
compareLists(L1, [], [], L2) :-
write("nList is Palindrome").
compareLists(L1, [X|List1], [X|List2], L2) :-
compareLists(L1, List1, List2, L2),
!.
compareLists(L1, [X|List1], [Y|List2], [Z|L2]) :-
write("nList is not Palindrome. "),
append(L1, L2, L),
printList(L).
код дает правильный результат для
palindrome([a,b,c,a]).
List is not Palindrome. a b c a c b a
palindrome([a,b,c]).
List is not Palindrome. a b c b a
однако для ввода, такого как
palindrome([a,b,c,b]).
List is not Palindrome. a b c b c b a
оптимальное решение, однако, должно быть
a b c b a
какие изменения я должен включить, чтобы иметь возможность достичь этого?
2 ответов
Я думаю, вам нужен предикат с двумя Args, In и Out:
pal([], []).
pal([X], [X]).
pal(In, Out) :-
% first we check if the first and last letter are the same
( append([H|T], [H], In)
% we must check that the middle is a palindrome
-> pal(T, T1),
append([H|T1], [H], Out)
; % if not, we remove the first letter
% and we work with the rest
In = [H|T],
% we compute the palindrome from T
pal(T,T1),
% and we complete the palindrome to
% fit the first letter of the input
append([H|T1], [H], Out)).
EDIT1 Этот код выглядит хорошо, но есть ошибка
? pal([a,b,c,a], P).
P = [a, b, c, b, a] .
должно быть [a,b, c, a, c, b, a] Я постараюсь все исправить.
EDIT2 Выглядит правильно :
build_pal([H|T], Out):-
pal(T,T1),
append([H|T1], [H], Out).
pal([], []).
pal([X], [X]).
pal(In, Out) :-
( append([H|T], [H], In)
-> pal(T, T1),
( T = T1
-> append([H|T1], [H], Out)
; build_pal(In, Out))
; build_pal(In, Out)).
С выход :
?- pal([a,b,c], P).
P = [a, b, c, b, a] .
?- pal([a,b,a], P).
P = [a, b, a] .
?- pal([a,b,c,b], P).
P = [a, b, c, b, a] .
?- pal([a,b,c,a], P).
P = [a, b, c, a, c, b, a] .
?- pal([a,b,a,c,a], P).
P = [a, b, a, c, a, b, a] .
первые 3 уравнения DCG захватывают шаблон палиндрома. Добавьте четвертый, покрывающий несоответствие, чтобы завершить спецификацию:
p([]) --> [].
p([T]) --> [T].
p([T|R]) --> [T], p(P), [T], {append(P,[T],R)}.
p([T|R]) --> [T], p(P), {append(P,[T],R)}.
?- phrase(p(L), [a,b,c,b]).
L = [a, b, c, b, a] ;
L = [a, b, c, c, b, a] ;
L = [a, b, c, b, c, b, a] ;
L = [a, b, c, b, b, c, b, a] ;
false.