开发者

Getting vertical lists of lists of lists in prolog?

a List of Lists like

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

and i want to get in this case all vertical lists like

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

how to do that? i thought about 2 counters witch work together like two "for to do" repeats. i need to check with "is_set" if [1,4,7] is a set or [3,6,3] witch of course is not.

like this:

el_at(Llist,Gl,1),

el_at(EList, Llist,1),
         globalListVertikalCheck(开发者_如何学PythonListVertikal),
         addlist(Elist,ListVertikal,NewListVertikal),

el_at(Llist,Gl,2),

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

thanks


A list of all vertical lists is known as a transposed matrix. SWI's library(clpfd) contains such code.


I didn't fully understand the solution you propose, but I have another one. I will try to describe how it works and maybe than you can see what was wrong with your solution and why it didn't work.

Let's consider an example of [[1,2], [3,4]]. The idea is to go through the first sub-list [1,2] and create an incomplete result [[1],[2]], then go through the next one [3,4] and prepend (which is easier than append in Prolog) each item in it to the each sub-list in the result. We will end up with [[3,1], [4,1]]. The sub-lists are then reversed and we have the result [[1,3],[1,4]].

Now the implementation: The vertical predicate is the core, it goes through the list of lists and the result is step by step accumulated in the Acc varible.

For each of the sublists, the vertical predicate calls the addfirst predicate, which takes each element of that sublist and prepends it to the list in which the previous results were accumulated.

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


Here goes a small implementation of transpose: It works by taking the first element of every sublist. When it finishes, it recursively does the same but now with the next item of each list, and so on.

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



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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜