List Prolog递归调用
我在递归搜索列表和根据结果创建列表列表时遇到问题 知识库包含团队名称、获胜次数和他们所在的区域,所有这些都与他们的团队编号关联。我正在传递List Prolog递归调用,list,recursion,prolog,List,Recursion,Prolog,我在递归搜索列表和根据结果创建列表列表时遇到问题 知识库包含团队名称、获胜次数和他们所在的区域,所有这些都与他们的团队编号关联。我正在传递团队中的团队编号列表,并且正在使用findMinMax/3搜索匹配对。我需要的结果是 成对团队列表(例如,X=[[gonzaga,华盛顿],[iowa,oklahoma],…]) 和1个不匹配的团队(由奇数个团队组成)或0个(偶数情况下) 我知道了所有其他的事情,并且可以达到部分[gonzaga,washington],但是在递归部分失败了 findPair(
团队中的团队编号列表
,并且正在使用findMinMax/3
搜索匹配对。我需要的结果是
成对团队列表(例如,X=[[gonzaga,华盛顿],[iowa,oklahoma],…]
)
和1个不匹配的团队(由奇数个团队组成)或0个(偶数情况下)
我知道了所有其他的事情,并且可以达到部分[gonzaga,washington]
,但是在递归部分失败了
findPair(Teams,[HL|TL],Rest) :-
findMinMax(Teams,Min,Max),
delete(Teams,Min,TeamsNoMin),
delete(TeamsNoMin,Max,Rest),
createPair(Min,Max,Pair), %Pair = "["Min_team","Max_team"]"
append(HL,[Pair],TL),
findPair(Rest,TL,[]).
一种通用的递归格式
在这里,我将尝试向您展示我们通常如何在Prolog中执行递归。对于初学者来说,获取列表并不简单,因为列表是“向后”构建的:在我们到达列表的末尾之前,没有任何东西能够真正构建
这种“向后构建”原则的原因是,一旦设置了一个变量,就不能将其设置为另一个值,因此,例如,很难说递归的第一步结果是[1]
,然后变成[1,2]
。相反,我们在Prolog中说的是,结果头是1
,结果尾是递归调用的结果(是的,如果它变得凌乱,请读两遍:d)。因此,只要我们没有碰到基本情况(没有执行递归的情况),我们就不会明确地绑定变量(即我们总是让术语的一部分未绑定)
对于谓词rec/2:rec(Input,Result)
通过将其元素与somepredicate/2
链接,从输入列表生成结果列表,我们将这样写:
rec([InputHead|InputTail], [ResultHead|ResultTail]) :-
somepredicate(InputHead, ResultHead),
rec(InputTail, ResultTail).
代表这一点
在这里您可以看到,我们声明结果的头部是ResultHead
,其尾部是通过调用rec(InputTail,ResultTail)计算出来的。
现在这很好,但我们需要在某个点停止,例如,当列表为空时。我们将这样写:
rec([], []).
这意味着:当输入列表为空时,结果列表也是空的
谓词的应用程序
现在,要解决问题,首先必须解决递归子句:
findPair(Teams,[HL|TL],Rest) :-
findMinMax(Teams,Min,Max),
delete(Teams,Min,TeamsNoMin),
delete(TeamsNoMin,Max,Rest),
createPair(Min,Max,Pair), %Pair = "["Min_team","Max_team"]"
append(HL,[Pair],TL),
findPair(Rest,TL,[]).
将成为
findPair(Teams, [Pair|Tail], LeftOver) :-
findMinMax(Teams, Min, Max),
delete(Teams, Min, TeamsNoMin),
delete(TeamsNoMin, Max, Rest),
createPair(Min, Max, Pair), %Pair = "["Min_team","Max_team"]"
findPair(Rest, Tail, LeftOver).
需要注意的重要事项:现在Rest
已成为两个独立的变量。findPair/3
的最后一个参数不再被更改,因为在递归调用中我们还不知道它的任何信息,所以我们无法绑定它,因此,in谓词Rest
现在是独立的,只代表尚未处理的团队,因此对结果列表的尾部(以及剩余的)感兴趣
现在我们必须处理基本情况:
- 当没有队伍的时候
findPair([], [], []).
这里我们说当团队
为空时,结果
和剩余
也是空的
- 当剩下一队的时候
findPair([Last], [], [Last]).
这里我们说,当团队
只有一个元素时,剩余
等于团队
,并且结果
为空
生成的代码是:
findPair([], [], []).
findPair([Last], [], [Last]).
findPair(Teams, [Pair|Tail], LeftOver) :-
findMinMax(Teams, Min, Max),
delete(Teams, Min, TeamsNoMin),
delete(TeamsNoMin, Max, Rest),
createPair(Min, Max, Pair), %Pair = "["Min_team","Max_team"]"
findPair(Rest, Tail, LeftOver).
要使您的子句具有排他性,您可以将团队
替换为[Not,Empty | AtAll]
,以确保最后一个子句仅用于长度为2或更长的列表,或者只需在子句开头添加一个保护,例如团队=[\uuuuu,| uuu],
希望有帮助,请不要犹豫,在评论中要求澄清:)感谢您的详细帮助!我知道我需要一些基本情况,但不确定该去哪里,因为我不能正确地找出递归部分。经过一段时间的修改,我终于可以让它工作了!Prolog快杀了我,我已经两周没学了。。。谢谢你的帮助,莫格!!!你应该接受一个你认为已经回答了你问题的答案。单击答案旁边的一个大的空V形轮廓。这将使你的声誉得分增加+2,并向所有人表明你的问题已经解决。当您有15个代表时,您还可以对任何您认为是好答案的答案进行投票。:)