Используя предикаты permutation/2
и prefix/2
, вы можете написать что-то вроде:
has_prefix_perm(List1, List2) :-
permutation(List2, Permutation),
prefix(Permutation, List1),
!.
В качестве примечания и цитаты Руководство по swi-прологу :
Обратите внимание, что список длины N имеет N! перестановки и генерация неограниченных перестановок становятся чрезмерно дорогими, даже для довольно коротких списков (10! = 3 628 800).
Так что я бы позаботился о том, чтобы не вызывать has_prefix_perm/2
со слишком длинным вторым списком, особенно если это не префикс по модулю перестановки, поскольку все случаи будут проверены.
Другим способом было бы проверить, являются ли элементы List1 членами List2, пока List2 не будет пустым, то есть вы знаете, что существует перестановка:
has_prefix_perm(_, []) :- !.
has_prefix_perm([Head1|List1], List2) :-
once(select(Head1, List2, Rest)),
has_prefix_perm(List1, Rest).
Написано так, я бы не стал использовать его в неосновных списках, но, увидев ваш ОП, я не стал искать дальше ...
Другим способом было бы проверить, является ли List1, уменьшенный до длины List2, перестановкой List2:
has_prefix_perm(List1, List2) :-
length(List2, L),
length(LittleL1, L),
append(LittleL1, _, List1),
permutation(LittleL1, List2),
!.
Другим способом было бы ... Я думаю, есть много способов сделать это, просто выберите тот, который не является ужасной по сложности и подходит вашему стилю! :)
Я бы пошел с последним лично.