#prolog
#prolog
Вопрос:
Итак, задача не такая сложная, но проблема в том, что я не могу использовать для этого сравнения терминов или чисел или сортировку. Я также сделал проверку, подтверждающую, что 2 списка содержат одни и те же элементы (так что эту часть можно игнорировать), но я не знаю, как выполнить проверку конкретно для вопроса. Например, если у меня есть это: List1 [1,2]
и List2 [1,2,1,2]
, это должно быть true, если List2 равно [1,2,2]
или [1,2,1,2,1]
должно быть false.
Комментарии:
1. Почему бы просто не взять меньший список, дублировать его в новый список с каждым элементом дважды, затем сгенерировать перестановки этого списка, и если один из них совпадает с другим списком, это верно?
2. Используйте рекурсию, если вы нашли первый элемент, затем выполните элемент в оставшемся списке.
Ответ №1:
Вот базовый подход, который не использует никаких чисел. Он использует dif/2
(альтернативно, use =
), что является «сравнением терминов», но не тем, который вы, возможно, имели в виду.
Во-первых, предикат для выражения того, что элемент встречается в списке ровно 0 раз (другими словами, он не является членом списка):
exactly0_list(_X, []).
exactly0_list(X, [Y | Ys]) :-
dif(X, Y),
exactly0_list(X, Ys).
Например:
?- exactly0_list(x, [a, b, c]).
true ;
false.
Но:
?- exactly0_list(b, [a, b, c]).
false.
Основываясь на этом, предикат для выражения того, что элемент встречается в списке ровно 1 раз:
exactly1_list(X, [X | Ys]) :-
exactly0_list(X, Ys).
exactly1_list(X, [Y | Ys]) :-
dif(X, Y),
exactly1_list(X, Ys).
Посмотрите, как это похоже. Это ведет себя следующим образом:
?- exactly1_list(b, [a, b, c]).
true ;
false.
?- exactly1_list(b, [a, b, c, b]).
false.
Если вы видите, что появляется шаблон, реализуйте предикат exactly2_list/2
в тех же строках. Он должен вести себя так:
?- exactly2_list(b, [a, b, c, b]).
true ;
false.
?- exactly2_list(b, [a, b, c, b, b]).
false.
Затем используйте это, чтобы сравнить каждый элемент вашего первого списка со вторым списком.
Комментарии:
1. Но это не используется, например, для
[1,1]
и[1,1,1,1]
, но должно
Ответ №2:
Я сделал свой подход следующим образом: «List1 [1,2] и List2 [1,2,1,2] должно быть true, если List2 равно [1,2,2] или [1,2,1,2,1] должно быть false».
1. Предикат check2times сравнивает 2 списка, затем вызывает проверку предиката. задача проверки — сравнить и дать общее количество пар, встречающихся в списке, в виде списка [1,1]. Затем используйте предикат sum для суммирования списка (например, [1,1] = 2 ). Затем просто проверьте, должна ли сумма = 2 возвращать true, иначе это будет false.
check2times([H|T],[H2|T2]):-
check([H|T],[H2|T2],N),
sum(N,S),
S=2.
2. проверьте предикат
check(_,[],[]).
check([A,B|T],[H1,H2|L],[N|R]):-
[A,B]=[H1,H2],
N is 1 0,
check([A,B|T],L,R).
check([A,B|T],[H1,H2|L],N):-
[A,B]=[H1,H2],
check([A,B|T],L,N).
3. предикат суммы
sum([],0).
sum([H|T],S):-
sum(T,S1),
S is S1 H.
Собрать все это вместе:
check2times([H|T],[H2|T2]):-
check([H|T],[H2|T2],N),
sum(N,S),
S=2.
check(_,[],[]).
check([A,B|T],[H1,H2|L],[N|R]):-
[A,B]=[H1,H2],
N is 1 0,
check([A,B|T],L,R).
check([A,B|T],[H1,H2|L],N):-
[A,B]=[H1,H2],
check([A,B|T],L,N).
sum([],0).
sum([H|T],S):-
sum(T,S1),
S is S1 H.
Примеры:
?-check2times([1,2],[1,2,1,2]).
true
false
check2times([1,2],[1,2,1]).
false
?-check2times([2,2],[2,2,2,2]).
true
false
?-check2times([2,2],[2,2,2,2,2,2]).
false
?-check2times([2,2],[2,4,3,5,2,2,3,6,5,3,2,2]).
true
false
?-check2times([b,b],[b,b,a,d,f,g,w,q,b,b,h,y]).
true
false
?-check2times([b,b],[b,b,5,6,f,g,1,2,b,b,h,y]).
true
false
?-check2times([1,2,3,4],[1,2,3,4,1,2,3,4,1,2,3,4]).
false
?-check2times([1,2,3,4],[1,2,3,4,1,2,3,4]).
true
false