所以我对Prolog很新。我需要编写一个代码段,无论嵌套有多深,都会计算列表中出现的任何数字的所有时间。例如, countNums([1,a,2,[3,b,4,[5,c,6]]],N) 应该返回N = 6
这是我的代码:
listp([]). %define listp's
listp([H|T]).
countNums([],0). %base case for empty list
countNums([H|T], N) :- listp(H). %check if head is a list
countNums([[H|T]|T1], N) :- countNums([H|T], N).
%check if head is not a number, if not do func with tail and dont increment
%if it is, do func with tail and increment N
countNums([H|T], N):- (
number(H) ->
countNums(T, N1),
N is N1+1;
countNums(T, N1),
N is N1).
所以,如果列表只是一个级别的列表(即[1,2,3]),这个代码将起作用,但如果它遇到任何新的级别(即[1,2,[3]]),它失败并退出。
我知道很多这段代码可能没有意义,但也许你们好的人可以帮助我吗?
答案 0 :(得分:1)
试试这个:
countNums([],0). %1
countNums([H|T],N) :- number(H), !, countNums(T,N1), N is N1 + 1. %2
countNums([[H|T1]|T2],N) :- !, countNums([H|T1],N1), countNums(T2,N2), N is N1 + N2. %3
countNums([_|T],N) :- countNums(T,N). %4
要将其分解,谓词(1)是空列表的基本情况;谓词(2)在列表上匹配,如果number(H)
的第一个目标成功,那么我们找到了一个数字,所以没有必要尝试任何其他谓词,因此切割(!
); (3)匹配当我们有一个列表,其中列表的头部也是一个列表,并且在这种情况下,我们不想尝试剩余的谓词,所以我们现在递归到头列表并计算尾巴,然后将两个结果加在一起;最后我们用(4)表示头部既不是数字也不是列表,所以我们只是跳过头部并计算尾部。
然后:
?- countNums([1, a, 2, [3, b, 4, [5, c, 6]]], N), write(N), nl, fail.
给了我这个:
6 No.
仅限一个解决方案,因fail
而失败。