Получение вертикальных списков списков списков в прологе? - PullRequest
2 голосов
/ 02 июня 2011

Список списков, таких как

Списки = [[1,2,3], [4,5,6], [7,8,3]]

и я хочу получить в этом случае все вертикальные списки, такие как

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

как это сделать? я думал о двух счетчиках, которые работают вместе, как два повторения «для того, чтобы сделать». мне нужно проверить с помощью is_set, если [1,4,7] является набором или [3,6,3] ведьмой, конечно, нет.

как это:

el_at (LLIST, Gl, 1), * +1019 *

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

el_at (LLIST, Gl, 2), * +1027 *

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

спасибо

Ответы [ 4 ]

3 голосов
/ 02 июня 2011

Список всех вертикальных списков называется транспонированной матрицей. Библиотека SWI (clpfd) содержит такой код.

0 голосов
/ 03 июня 2011

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 голосов
/ 02 июня 2011

Вот небольшая реализация транспонирования: он работает, беря первый элемент каждого подсписка.Когда он заканчивается, он рекурсивно делает то же самое, но теперь со следующим элементом каждого списка и т. Д.

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]).
0 голосов
/ 02 июня 2011

Я не совсем понял решение, которое вы предлагаете, но у меня есть другое. Я постараюсь описать, как это работает, и, возможно, чем вы сможете понять, что не так с вашим решением и почему оно не работает.

Давайте рассмотрим пример [[1,2], [3,4]]. Идея состоит в том, чтобы пройти через первый подсписок [1,2] и создать неполный результат [[1], [2]], затем перейти к следующему [3,4] и подготовить (что проще, чем добавить). в прологе) каждый элемент в нем для каждого подсписка в результате. Мы закончим с [[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).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...