2014-10-01 2 views
0

У меня есть большой список BIGLIST, который состоит исключительно из любого количества небольших списков SMALLLIST, которые сами содержат другой список INNERLIST в своем первом указателе. Мне нужно спроектировать предикат, который может найти SMALLLIST с помощью кратчайшего INNERLIST. Нет INNERLIST не имеет длину больше 9. Например:Prolog - Поиск объекта с самым коротким внутренним списком в списке

BIGLIST = [ 
      [[1,2,3],3824], 
      [[4,5],89], 
      [[6],283], 
      [[2],14], 
      ] 

SMALLLIST с кратчайшим INNERLIST здесь [[6],283], несмотря на существование [[2],14] (они имеют одинаковую длину). Я написал предикат shortest/2 вроде следующего, но желаемый SMALLLIST никогда не будет привязан к Shortest:

shortest(BIGLIST,Shortest) :- 
    Num = 10, 
    get_shortest(BIGLIST,Shortest,Num). 

get_shortest([],_,_).         %list is empty, stop 
get_shortest([SMALLLIST|Tail],Shortest,ShortLen) :- %better SMALLLIST found 
    nth0(0,SMALLLIST,INNERLIST),       %get INNERLIST 
    length(INNERLIST,Len), 
    Len < ShortLen, 
    NShortest = SMALLLIST, 
    NShortLen = Len, 
    get_shortest(Tail,NShortest,NShortLen), 
    Shortest = NShortest. 
get_shortest([_|T],Shortest,ShortLen) :-    %skip head if it is not a better value 
    get_shortest(T,Shortest,ShortLen). 

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

+1

Вы можете сделать что-то вроде 'setof (N- [L | T], (член ([L | T], B IGLIST), length (L, N)), S), S = [_-SMALLIST | _]. 'Но он выберет последний из самых коротких, если есть« галстук », а не первый. – lurker

+0

'Head' должен быть' SMALLLIST', но есть и другие недостатки в вашем коде. Считаете ли вы использование '->'? И если вы просто хотите голову, используйте '[INNERLIST | _] = SMALLLIST'. –

ответ

1

В таких случаях keysort/2 пригодится. Например:

biglist_smallest(Bs, E) :- 
     maplist(element_with_length, Bs, LEs), 
     keysort(LEs, [_-E|_]). 

element_with_length(Elem, L-Elem) :- 
     Elem = [Inner|_], 
     length(Inner, L). 

С вашими данными:

biglist([[[1,2,3],3824], 
     [[4,5],89], 
     [[6],283], 
     [[2],14] 
     ]). 

мы получаем:

?- biglist(Ls), biglist_smallest(Ls, E). 
Ls = [[[1, 2, 3], 3824], [[4, 5], 89], [[6], 283], [[2], 14]], 
E = [[6], 283]. 
0

Фигурные его, как позже 10 минут, сделал что-то вроде этого:

shortest(BIGLIST,Shortest) :- 
    Num = 10, 
    get_shortest(BIGLIST,Num,_,Shortest). 

get_shortest([],_,S,S). 
get_shortest([SMALLLIST|Tail],ShortLen,_,Result) :- 
    nth0(0,SMALLLIST,INNERLIST), 
    length(INNERLIST,Len), 
    Len < ShortLen, 
    NShortest = SMALLLIST, 
    NShortLen = Len, 
    get_shortest(Tail,NShortLen,NShortest,Result). 
get_shortest([_|T],ShortLen,Shortest,Result) :- 
    get_shortest(T,ShortLen,Shortest,Result). 
Смежные вопросы