我有一个方法可以遍历一个数字 X,并计算它有多少个数字是偶数(这是 Y 参数的目的)
count_even(0,_). %base case
count_even(X,Y) :- mod(X,2)=:=0,%recursive case
Y1 is Y + 1,
X1 is X // 10, %if X is even
count_even(X1,Y1)
; mod(X,2)\==0, %if X is odd
X1 is X // 10,
count_even(X1,Y).
当然,通过调用 count_even(insert any number, 0) 并在基本情况下添加 write(y) 很容易获得结果,但是我需要确保当您为第二个参数输入变量时,该方法有效,例如 count_even(insert any number, A)
当然,这需要实例化 Y,但是在递归方法中放置一个简单的 Y is 0 将导致 Y 始终为 0 或 1,我不希望这样。有什么想法吗?
答案 0 :(得分:0)
您可以在基本情况下使用 Y
扭转计算并实例化 0
。在偶数位的每一步中,它都会递增。
其他问题:在递归情况下,您必须确保X > 0
,否则在回溯过程中您会得到其他错误答案。此外,算术不等于是 =\=
(\==
代替统一项,否定,这对于 mod(8,2)==0
也是如此)。这也会给您带来额外的错误结果。
固定代码:
count_even(0,0). %base case
count_even(X,Y) :- X > 0, X1 is X // 10, %recursive case
((mod(X,2)=:=0, count_even(X1,Y1), Y is Y1 + 1); %if X is even
(mod(X,2)=\=0, count_even(X1,Y))). %if X is odd
答案 1 :(得分:0)
尝试这样的事情:
even_digits( N, Y ) :- % the general case
N > 0, % - for N > 0,
N1 is div(N,10) , % - get all digits to the left of the one's place
D is mod(N,10) , % - get the one's digit
even_digits(N1,T) , % - recurse down on N1
( is_even(D) % - if the one's digit is even
-> Y is T+1 % - add 1 to the earlier result
; Y is T % - otherwise, we're done.
). % Easy!
even_digits( 0, 0 ). % the base case. The question is... is zero even, odd, or signless. I've decided that it is signless here.
is_even(N) :- 0 =:= mod(N,2).
但这会让你处于一个零的奇怪地方。零是我们用完正数中的数字的点,但它本身也是一个数字。
您可能会发现将数字视为原子并将其分解为数字列表更容易。
even_digits( N, R ) :-
number_chars(N,Ds),
even_digits( Ds, 0 , R ).
even_digits( [] , N , N ).
even_digits( [D|Ds] , T , N ) :-
( member( D, ['0','2','4','6','8'] )
-> T1 is T+1
; T1 is T
),
even_digits(Ds, T1, N).
这适用于负数、零、带小数值的数字。