2012-03-19 3 views
3

Можно ли получить все элементы из списка списков в Prolog?Получить элементы из списка списков

Что-то вроде: У нас есть getElements ([[[a, b, [c]], d, e], f, g, [h, [i, j]]], S), и результат: S = [a, b, c, d, e, f, g, h, i, j] ...

Спасибо за помощь.

+0

исследовательская панель + «сгладить» должно сделать вас счастливым. – m09

ответ

2

В SWI-Prolog (и, может быть, другие), вы можете использовать flatten/2:

?- flatten([[[a,b,[c]],d,e],f,g,[h,[i,j]]], S). 
S = [a, b, c, d, e, f, g, h, i|...]. 

Обратите внимание, что the SWI-Prolog manual page for flatten/2 включает в себя следующее заявление:

Ending до нуждающихся выравниваться/3 часто указывает на, как append/3 для добавления двух списков, плохой дизайн.

Однако на странице не указано, есть ли другой собственный предикат для его замены.

Я уверен, что будет предоставлен лучший ответ.

+0

ok thanks :) did not знаю это ... хотя я надеялся немного, что я узнаю трюк - какой-то алгоритм ... но спасибо;) (и извините за мой английский O :-)) – kolage

+1

Вы можете увидеть источник/как это реализовано здесь. http://www.swi-prolog.org/pldoc/doc/swi/library/lists.pl?show=src – magus

+3

@magus: этот предикат устарел. Пожалуйста, прочтите это обоснование в источнике, о котором вы упоминаете: Завершение необходимости сглаживания/3 часто указывает, как append/3 для добавления двух списков, плохой дизайн . Эффективный код, который генерирует списки из сгенерированных небольших списков, должен использовать разницу списки, часто возможные с помощью правил грамматики для оптимальной читабельности. – false

3

Вы запросили все элементы списка списков. То есть для [[1,2,3],[4]] это будет список [1,2,3,4]. Однако для [[[1],[3]]] это будет список [[1],[3], так как [1] и [3] являются элементами. По этой причине flatten/2 неверен, он дает вам [1,3] в качестве ответа. Кроме того, для 1 это дает [1] ...

Вот решение, использующее :

seq([]) --> []. 
seq([E|Es]) --> [E], seq(Es). 

seqq([]) --> []. 
seqq([Es|Ess]) --> seq(Es), seqq(Ess). 

?- phrase(seqq([[[1],[3]]]), Xs). 
Xs = [[1],[3]]. 

?- phrase(seqq(1), Xs). 
false. 

Это решение теперь работает и в тех случаях, как следующее:

?- phrase(seqq([S1,S2]), [1,2]). 
S1 = [], 
S2 = [1,2] ; 
S1 = [1], 
S2 = [2] ; 
S1 = [1,2], 
S2 = [] ; 
false. 

В то время как flatten/2 полностью неправильный:

?- flatten([S1,S2],[1,2]). 
S1 = 1, 
S2 = 2. 
Смежные вопросы