我有一个大型列表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).
感谢您的帮助。
答案 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).