问题描述
这是我的代码,问题是,列表的最后一个元素不是绝对值。有人可以帮忙吗?
maxlist( [X],X ).
maxlist( [X,Y|Rest],AbsMax ) :-
abs( [X],AbsX ),maxlist( [Y|Rest],AbsMaxRest ),max( AbsX,AbsMaxRest,AbsMax ).
max( X,Y,X ) :- X >= Y.
max( X,Y ) :- X < Y.
abs( [X],Y ) :-
X < 0 -> Y is -X ; Y = X.
对于这样的列表:
maxlist( [-4110,-11,-885,-45,-154,-995],X )
我得到 X = 4110
,但对于最后一项
maxlist( [-995,-4110],X )j
我得到 X = 995
,而我应该得到 4110
。
解决方法
您代码中的基本问题是列表的最后一个元素永远不会采用其绝对值。此外,您不需要为绝对值或最大值实现谓词:它们已被写入 Prolog。
Prolog 中的一个常见习语是将公共谓词与“私有”辅助谓词一起使用,该辅助谓词带有一个或多个附加参数,这些参数携带计算所需的状态。这也有助于将事情转化为尾递归优化所需的形式,通过允许重用堆栈帧将递归转换为简单的迭代。
尝试这样的事情:
max_list( [X|Xs],M ) :- % to compute the maximum absolute value of a list ...
A is abs( X ),% * Pop the head of the list and take its absolute value,then...
max_list( Xs,A,M ) . % * Invoke the helper,seeding the accumulator with A
max_list( [],M,M ) . % If the source list is empty,we're done.
max_list( [X|Xs],T,M ) :- % Otherwise...
X1 is abs(X),% * Take the absolute value of X
T1 is max(X1,T),% * Determine the max of X1 and T
max_list(Xs,T1,M ) % * Recurse down with the remainder of the list and the new accumulator value
. % Easy!
如果您需要自己计算 max
或 abs
,这很简单:
max( X,Y,Max ) :- X > Y -> Max is X ; Max is Y .
abs( X,Abs ) :- X >= 0 -> Abs is X ; Abs is -X .
,
maxlist([X],X).
maxlist([X,Y|Rest],AbsMax) :-
abs(X,AbsX),abs(Y,AbsY),maxlist([AbsY | Rest],AbsMaxRest),max(AbsX,AbsMaxRest,AbsMax).
max(X,X) :- X>= Y.
max(X,Y) :- X < Y.
abs(X,Y) :- X < 0 -> Y is -X ; Y = X.
这解决了整个整数列表