【问题标题】:Prolog - Finding object with shortest inner List in a ListProlog - 在列表中查找具有最短内部列表的对象
【发布时间】:2014-11-26 15:32:24
【问题描述】:

我有一个大列表 BIGLIST,它仅由任意数量的较小列表 SMALLLIST 组成,它们本身在其第一个索引中包含另一个列表 INNERLIST。我需要设计一个谓词,可以找到最短INNERLISTSMALLLIST。没有INNERLIST 的长度大于 9。例如:

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

尽管存在[[2],14](它们的长度相同),但这里INNERLIST 最短的SMALLLIST[[6],283]。我写了一个谓词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).

感谢您的帮助。

【问题讨论】:

  • 你可以这样做,setof( N-[L|T], (member([L|T], BIGLIST), length(L, N)), S ), S = [_-SMALLIST|_]. 但如果有“领带”,它会选择最短的最后一个,而不是第一个。
  • Head 应该是 SMALLLIST,但是您的代码中还有其他缺陷。您是否考虑过使用-&gt;?如果您只想要头部,请使用[INNERLIST|_]=SMALLLIST

标签: list variables recursion binding prolog


【解决方案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].

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2023-03-16
      • 2019-04-03
      • 2017-03-26
      • 2015-02-24
      • 2013-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多