我写了一个谓词,它应该计算一个列表的长度:
my_length([],0).
my_length([_|L],N) :- my_length(L,N1), N is N1 + 1.
任何人都可以帮忙调整这个,以便它会获取列表列表并输出列表列表中的元素总数吗?
答案 0 :(得分:2)
您拥有所需的大部分内容:添加一条规则,用于计算将头部传递到my_length
的列表列表的长度:
my_length_lol([], 0).
my_length_lol([H|L],N) :- my_length(H,Add), my_length_lol(L,N1), N is N1 + Add.
正如您所看到的,my_length_lol
(" lol"代表"列表列表")是my_length
的近似完整副本。唯一的区别是它不会忽略列表头,并使用my_length
规则来计算子列表的长度。
答案 1 :(得分:1)
在此回答中,我们将meta-predicate foldl/4
与Prolog lambda expressions结合使用。
:- use_module(library(lambda)).
我们像这样定义谓词lists_length/2
:
lists_length(Xss,N) :-
foldl(\Xs^N0^N2^(length(Xs,N1),N2 is N0+N1), Xss, 0,N).
示例查询:
?- lists_length([[a,b,c],[],[d,e]], N).
N = 5.
答案 2 :(得分:1)
我仍然不是foldl/4
的最大粉丝,因此我觉得更自然地说:
xss_length(Xss, N) :-
maplist(length,Xss, Ns),
list_sum(Ns, N).
但是,这不会因Xss = [_,_], xss_length(Xss, 2)
而终止。但这是一个开始。
答案 3 :(得分:1)
通过使用累加器可以使@dasblinkenlight和问题中的原始代码发布尾递归,这将允许在恒定空间中运行:
my_length(List, Length) :-
my_length(List, 0, Length).
my_length([], Length, Length).
my_length([_| Tail], Length0, Length) :-
Length1 is Length0 + 1,
my_length(Tail, Length1, Length).
my_length_lol(Lists, TotalLength) :-
my_length_lol(Lists, 0, TotalLength).
my_length_lol([List| Lists], TotalLength0, TotalLength) :-
my_length(List, Length),
TotalLength1 is TotalLength0 + Length,
my_length_lol(Lists, TotalLength1, TotalLength).