我需要创建一个具有输入列表的规则,然后一次从中获取2个值,比较它们并创建一个具有更大值的新列表。
它需要像这样工作:
INPUT:bigger([1,2,6,8,5], X).
输出:X = [2,6,8,8,5].
这是我的代码:
%stop
bigger([],_).
%last element
bigger([H1|[]],L2):-
append(L2, [H1], L3),
bigger([],L3).
%compare first 2
bigger([H1,H2|T], L2):-
( H1 > H2,
append(L2, [H1], L3),
bigger([H2|T], L3) )
;
( H2 > H1,
append(L2, [H2], L3),
bigger([H2|T], L3) ).
如果我用
替换基础案例 %stop
bigger([],L):-
write(L).
然后我会得到这个输出:
[2,6,8,8,5]
X = [] ;
[_G3685,2,6,8,8,5]
X = [_G3685] ;
[_G3685,_G3691,2,6,8,8,5]
X = [_G3685, _G3691] ;
[_G3685,_G3691,_G3697,2,6,8,8,5]
X = [_G3685, _G3691, _G3697]
.
我可以看到,当它到达基本情况时,技术上第二个变量具有正确的值。但随后它统一到一个空列表。不仅如此,它还会继续添加未知元素。
我该如何处理?
答案 0 :(得分:1)
有些事情你需要改变。例如,条款:
bigger([H1|[]],L2):-
append(L2, [H1], L3),
bigger([],L3).
调用更大的([],L3),它与条款bigger([],_).
匹配但'_'
与任何内容匹配,因此这会为您提供未知元素。使用append并不是一个好主意,但使用模式匹配会更好:
bigger([],[]).
bigger([H],[H]).
bigger([H1,H2|T], [X|T1]):-
( H1 > H2->
X=H1,
bigger([H2|T], T1)
;H2 > H1->
X=H2,
bigger([H2|T],T1) ).
这里,您在每次递归调用中实例化输出列表L3的一个元素,并对其余元素执行相同操作,直到它有一个元素。仅当输入为空列表时,子句bigger([],[]).
才有用。当输入不为空时,当列表中有一个元素离开时,递归停止。此外,最好将->
用于if-else语句。
结果:
?- bigger([1,2,6,8,5], X).
X = [2, 6, 8, 8, 5] ;
false.