Prolog作业:使用insert函数实现列表排列函数时遇到问题
两种Prolog排列生成函数的实现(基于delete和insert)
没问题,我来帮你补全基于insert/3的排列生成器,同时把两种实现的逻辑和代码都梳理清楚!
首先,先确认你已有的基础代码是正确的:
% 连接两个列表 join([], L, L). join([X|L1], L2, [X|L3]) :- join(L1, L2, L3). % delete(X, L1, L2):L2是L1删除X后的列表 delete(X, L1, L2) :- join(L3, [X|L4], L1), join(L3, L4, L2). % insert(X, L1, L2):L2是L1插入X后的列表 insert(X, [], [X]). insert(X, L1, L2) :- delete(X, L2, L1).
1. 基于delete/3的排列函数perm_delete/2
这个实现的核心逻辑是:
- 空列表的排列只有它自己
- 要生成一个列表的排列,先从列表中选出任意一个元素作为排列的第一个元素,然后递归生成剩余列表的排列,组合起来就是完整的排列。
代码实现:
% perm_delete(L, P):P是列表L的一个排列 perm_delete([], []). perm_delete(L, [X|P]) :- delete(X, L, Rest), % 从L中删除X得到剩余列表Rest perm_delete(Rest, P).% 递归生成Rest的排列P
测试示例:
?- perm_delete([1,2,3], P). P = [1,2,3] ; P = [1,3,2] ; P = [2,1,3] ; P = [2,3,1] ; P = [3,1,2] ; P = [3,2,1] ; false.
2. 基于insert/3的排列函数perm_insert/2
这个实现的思路和delete版本相反:
- 空列表的排列只有它自己
- 要生成列表
[X|Xs]的排列,先生成子列表Xs的所有排列,然后把X插入到这些排列的任意位置,得到的就是原列表的所有排列。
代码实现:
% perm_insert(L, P):P是列表L的一个排列 perm_insert([], []). perm_insert([X|Xs], P) :- perm_insert(Xs, P_rest), % 递归生成Xs的排列P_rest insert(X, P_rest, P). % 把X插入P_rest的任意位置得到P
测试示例:
?- perm_insert([1,2,3], P). P = [1,2,3] ; P = [2,1,3] ; P = [2,3,1] ; P = [1,3,2] ; P = [3,1,2] ; P = [3,2,1] ; false.
两种实现都能正确生成列表的所有排列,只是递归的方向不同:delete版本是从原列表逐步拆分元素,insert版本是从空列表逐步插入元素构建排列。
内容的提问来源于stack exchange,提问作者Mitchell Faas
相关产品推荐
相关产品推荐

