prolog中计算正数和负数的尾部递归程序
我想在prolog中编写一个尾部递归程序:prolog中计算正数和负数的尾部递归程序,prolog,tail-recursion,Prolog,Tail Recursion,我想在prolog中编写一个尾部递归程序:count_neg(Ls,N,R)如果Ls是一个整数列表,而N是负元素的数量,则这是真的R应表示非负元素列表 例如: count_neg([1,-2,0,1,2,-3],N,R). N = 2, R = 4. 以下是我迄今为止编写的代码: count_neg(Ls, N, R) :- count_neg(Ls, 0, 0, N, R). count_neg([L|Ls], Cnt1, Cnt2, N, R) :- (L > 0 -> C1
count_neg(Ls,N,R)
如果Ls
是一个整数列表,而N
是负元素的数量,则这是真的<代码>R应表示非负元素列表
例如:
count_neg([1,-2,0,1,2,-3],N,R).
N = 2,
R = 4.
以下是我迄今为止编写的代码:
count_neg(Ls, N, R) :- count_neg(Ls, 0, 0, N, R).
count_neg([L|Ls], Cnt1, Cnt2, N, R) :- (L > 0 -> C1 is Cnt1 + 1, !; L < 0 -> C2 is Cnt2 + 1, !), count_neg(Ls, C1, C2, N, R).
count_neg([], Cnt1, Cnt2, N, R) :- N is Cnt1.
count_neg([], Cnt1, Cnt2, N, R) :- R is Cnt2.
count_neg(Ls,N,R):-count_neg(Ls,0,0,N,R)。
计数负([L | Ls],Cnt1,Cnt2,N,R):-(L>0->C1是Cnt1+1,!;L<0->C2是Cnt2+1,!),计数负(Ls,C1,C2,N,R)。
计数负([],Cnt1,Cnt2,N,R):-N是Cnt1。
计数负([],Cnt1,Cnt2,N,R):-R是Cnt2。
问题是,N
和R
在开始时都用0初始化,这是正确的,但是当程序应该计数第一个负数时,它不会从零开始计数,而是从_21532开始计数,结果是错误的:
有人知道这里出了什么问题吗?我还想在我的程序中使用Cuts。问题在于您没有正确更新索引,并且调用谓词
is/2
,参数没有实例化。
一个可能的解决办法是:
count_neg(Ls, N, R):-
count_neg(Ls, 0, 0, N, R).
count_neg([],C1,C2,C1,C2).
count_neg([L|Ls], Cnt1, Cnt2, N, R):-
(L > 0 ->
C1 is Cnt1 + 1,
C2 is Cnt2
;
C2 is Cnt2 + 1,
C1 is Cnt1),
count_neg(Ls, C1, C2, N, R).
?- count_neg([1,-2,0,1,2,-3,8],N,R).
N = 4
R = 3
另外,您不需要最后两个谓词和剪切。在问题中,你说R
应该表示一个列表,但在前面的解决方案中,你没有得到列表。要获得它,您可以如下修改程序:
countNeg(L,N,R):-
countNeg(L,N,0,R,[]).
countNeg([],N,N,R,R).
countNeg([H|T],N,C,R,L1):-
( H < 0 ->
C1 is C+1,
countNeg(T,N,C1,R,L1);
append(L1,[H],L2),
countNeg(T,N,C,R,L2)).
?- countNeg([1,-2,0,1,2,-3],N,R).
N = 2
R = [1, 0, 1, 2]
countNeg(L,N,R):-
countNeg(L,N,0,R,[])。
countNeg([],N,N,R,R)。
countNeg([H | T],N,C,R,L1):-
(H<0->
C1是C+1,
countNeg(T,N,C1,R,L1);
附加(L1[H],L2),
countNeg(T,N,C,R,L2))。
?-countNeg([1,-2,0,1,2,-3],N,R)。
N=2
R=[1,0,1,2]
在这个解决方案中,您还可以注意到,您在每个分支中调用了
countNeg/5
(我检查<0
,而在前面的例子中,您检查>0
)。为什么所有的剪切?