【问题标题】:Getting vertical lists of lists of lists in prolog?在prolog中获取列表列表的垂直列表?
【发布时间】:2011-06-02 14:28:53
【问题描述】:

列表列表,如

列表=[ [1,2,3], [4,5,6], [7,8,3]]

我想在这种情况下获得所有垂直列表,如

[1,4,7], [2,5,8], [3,6,3]

怎么做?我想 2 个柜台女巫像两个“待办事项”重复一样一起工作。 如果 [1,4,7] 是一组或 [3,6,3] 女巫当然不是,我需要检查“is_set”。

像这样:

el_at(Llist,Gl,1),

el_at(EList, Llist,1),
         globalListVertikalCheck(ListVertikal),
         addlist(Elist,ListVertikal,NewListVertikal),

el_at(Llist,Gl,2),

el_at(EList, Llist,2),
       globalListVertikalCheck(ListVertikal),
       addlist(Elist,ListVertikal,NewListVertikal),

谢谢

【问题讨论】:

    标签: list prolog


    【解决方案1】:

    所有垂直列表的列表称为转置矩阵。 SWI's library(clpfd) 包含这样的代码。

    【讨论】:

      【解决方案2】:

      我没有完全理解您提出的解决方案,但我有另一个解决方案。我将尝试描述它是如何工作的,也许你会看到你的解决方案出了什么问题以及为什么它不起作用。

      让我们考虑一个 [[1,2], [3,4]] 的例子。这个想法是通过第一个子列表 [1,2] 并创建一个不完整的结果 [[1],[2]],然后通过下一个 [3,4] 并预先添加(这比追加更容易在 Prolog 中)其中的每个项目到结果中的每个子列表。我们最终会得到 [[3,1], [4,1]]。然后反转子列表,得到结果 [[1,3],[1,4]]。

      现在实现: vertical 谓词是核心,它遍历列表列表,结果逐步累积到 Acc 变量中。

      对于每个子列表,vertical 谓词调用 addfirst 谓词,该谓词获取该子列表的每个元素并将其添加到之前累积结果的列表中。

      vertical([X|Xs],Result):-
          createempty(X, Acc),
          vertical([X|Xs], Acc, ReversedResults),
          reverseall(ReversedResults, Result).
      
      reverseall([], []).
      reverseall([X|Xs], [XReversed|Rest]):-
          reverse(X, XReversed),
          reverseall(Xs, Rest).
      
      createempty([], []).
      createempty([X|Xs], [[]|R]):-createempty(Xs,R).
      
      vertical([], Result, Result).
      vertical([X|Xs], Acc, Result):-
          addfirst(X, Acc2, Acc),
          vertical(Xs, Acc2, Result).
      
      addfirst([], [], []).   
      addfirst(
          [Y|Ys], 
          [[Y|YVerticalRest]|ResultRest], 
          [YVerticalRest|VerticalsRest]):-
          addfirst(Ys, ResultRest, VerticalsRest).
      

      【讨论】:

        【解决方案3】:

        下面是转置的一个小实现: 它通过获取每个子列表的第一个元素来工作。当它完成时,它会递归地执行相同的操作,但现在使用每个列表的下一项,依此类推。

        transpose(M, T):-
          transpose(M, [], T).
        
        transpose([], [], []).
        transpose([], S, [[]|T]):-
          S \= [] ->
           (reverse(S, M), transpose(M, [], T)).
        transpose([[]|MTail], S, T):-
          transpose(MTail, S, T).
        transpose([[Item|Tail]|MTail], S, [[Item|NTail]|T]):-
          transpose(MTail, [Tail|S], [NTail|T]).
        

        【讨论】:

          【解决方案4】:
          
          transpose([[]|_],[]) :- !.
          transpose(L,[L1|R2]) :-
                  transpose(L,L2,L1),
                  transpose(L2,R2).
          
          transpose([],[],[]) :- !.
          transpose([[A|R1]|R2],[R1|R3],[A|R4]) :-
                  transpose(R2,R3,R4).
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-11-05
            • 2017-03-26
            • 1970-01-01
            • 2023-01-12
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多