2014-10-01 82 views
0

我有一個大列表BIGLIST,它僅包含任意數量的較小列表SMALLLIST,它們本身在其第一個索引中包含另一個列表INNERLIST。我需要設計一個謂詞,可以找到最短的INNERLISTSMALLLIST。沒有INNERLIST具有的長度大於9例如:Prolog - 查找列表中列表最短的對象列表

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

具有最短INNERLISTSMALLLIST這裏是[[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],(member([L | T] ,BIGLIST),length(L,N)),S),S = [_-SMALLIST | _]。「但是如果存在」tie「而不是第一個,它會選擇最短的最後一個。 – lurker 2014-10-01 18:16:29

+0

'Head'應該是'SMALLLIST',但是代碼中還有其他缺陷。你有沒有考慮過使用' - >'?如果您只想要頭部,請使用'[INNERLIST | _] = SMALLLIST'。 – 2014-10-01 18:34:49

回答

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).