查找列表列表的长度

时间:2014-11-24 18:06:27

标签: prolog nested-lists

我写了一个谓词,它应该计算一个列表的长度:

 my_length([],0).
 my_length([_|L],N) :- my_length(L,N1), N is N1 + 1.

任何人都可以帮忙调整这个,以便它会获取列表列表并输出列表列表中的元素总数吗?

4 个答案:

答案 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规则来计算子列表的长度。

Demo.

答案 1 :(得分:1)

在此回答中,我们将 foldl/4Prolog 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).
相关问题