2014-11-24 4 views
2

Я написал предикат, который должен вычислить длину списка:Найти длину списка списков

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

кто-нибудь помочь в настройке это так, что он будет принимать список списков и вывода общего числа элементов в списке списков?

+0

Просто сделайте другой предикат, аналогично этому, но вместо добавления 1 добавьте результат my_length. –

+0

Если вы можете использовать существующие предикаты Prolog (если они находятся в вашей библиотеке Prolog), вы также можете просто сделать my_length (L, N): - flatten (L, F), length (F, N) .' – lurker

ответ

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.

+0

Perfect. Огромное спасибо. – GregH

+1

Использование имен переменных, таких как 'Xs' и' Xss', помогло бы – false

1

В ответ мы используем 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. 
+0

Незначительное замечание о соглашениях: для различий весьма полезно отметить их ** удалением ** разделительных пространств. Таким образом, 'foldl (..., 0, L)' – false

1

Я до сих пор не самый большой поклонник foldl/4 и, таким образом, я считаю, это намного более естественно состояние:

xss_length(Xss, N) :- 
    maplist(length,Xss, Ns), 
    list_sum(Ns, N). 

Тем не менее, это не заканчивается для Xss = [_,_], xss_length(Xss, 2). Но это начало.

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). 
Смежные вопросы