Prolog - 在列表中查找具有最短内部列表的对象

时间:2014-10-01 17:43:57

标签: list variables recursion binding prolog

我有一个大型列表BIGLIST,它只包含任意数量的较小列表SMALLLIST,它们在第一个索引中包含另一个列表INNERLIST。我需要设计一个可以找到最短SMALLLIST的{​​{1}}的谓词。否INNERLIST的长度大于9.例如:

INNERLIST

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

感谢您的帮助。

2 个答案:

答案 0 :(得分: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].

答案 1 :(得分: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).