我正在使用Prolog样本列表程序并进行操作以对它们进行一些操作。但是,我陷入困境,无法找到任何解决方案或样本。
我想写一个函数,它接受两个整数列表并返回一个浮点值。两个列表大小相等。浮点值是比较结果除以列表大小。
该功能应该将第一个列表的每个元素与第二个列表的每个元素进行比较。一对(i,j)是i是第一列表中元素的位置,j是第二列表中元素的位置。如果元素i大于元素j,则比较结果增加1.如果元素i小于元素j,则比较结果减1.如果相等,则不会发生任何事情。在上面的操作结束时,我们返回上面描述的浮点值。
示例:
retVal([4,5,3], [8,2,1], Result).
应返回Result =( - 1 + 1 + 1-1 + 1 + 1-1 + 1 + 1)/ 3 = 0.33
在面向对象语言中,它就像在控制台上打印一样简单。但是,我在Prolog中没有任何想法。提前谢谢。
答案 0 :(得分:0)
我认为这应该有效:
sgn(X, Y, -1) :- X<Y.
sgn(X, Y, 1) :- X>Y.
sgn(X, X, 0).
ssapd(L, R, O) :- ssapd(L, R, R, 0, 0, O).
ssapd([LI | LR], RL, [RPI | RPL], ACC, ACCL, O) :-
sgn(LI, RPI, SGN), !,
ACC1 is ACC + SGN,
ssapd([LI | LR], RL, RPL, ACC1, ACCL, O).
ssapd([_ | LR], RL, [], ACC, ACCL, O) :-
ACCL1 is ACCL + 1,
ssapd(LR, RL, RL, ACC, ACCL1, O).
ssapd([], _, _, ACC, ACCL, Result) :-
Result is ACC / ACCL.
这是一个很好的实现,通过使用两个累加器,O(n²)时间复杂度和常量内存(输入大小除外)完成尾递归。要执行它,请尝试:
ssapd([4,5,3], [8,2,1], Result).
答案 1 :(得分:0)
这是一种尾递归方法:
compare_list( Xs , Ys , Z ) :-
compare_list( Xs, Ys, 0 , 0 , S , L ) ,
Z is float(S)/float(L)
.
compare_list( [] , [] , S , L , S , L ) .
compare_list( [X|Xs] , [Y|Ys] , A , B , S , L ) :-
A1 is A + sign(X-V) ,
B1 is B + 1 ,
compare_list(Xs,Ys,A1,B1,S,L)
.
另一种方法,这次&#34;头部递归&#34;:
compare_list( Xs , Ys , Z ) :-
compare_list( Xs , Ys , S , L ) ,
Z is float(S)/float(L)
.
compare_list( [] , [] , 0 , 0 ) .
compare_list( [X|Xs] , [Y|Ys] , S , L ) :-
compare_list(Xs,Ys,S1,L1) ,
S is S1 + sign(X-Y) ,
L is L1 + 1
.
前一个实现不会在长列表上溢出堆栈,因为它被优化到[有效]迭代,但需要累加器;后一种实现方式并不需要累加器,但如果列表的长度足够,则会烧掉堆栈。
答案 2 :(得分:0)
您通过文字描述的内容可能是此代码段
retVal(L1,L2, Result) :-
findall(S, (member(X1,L1), member(X2,L2), (X1 < X2 -> S = -1 ; S = 1)), L),
sum_list(L, Sum),
length(L1, Len),
Result is Sum / Len.
唉,测试结果与您的期望不符合
?- retVal([4,5,3], [8,2,1], X).
X = 1.
正如liori在评论中指出的那样,您的手动计算不正确......