不确定你的例子是否正确,但我明白了.
如果使用SWI-PROLOG,您可以使用CLPFD模块,如下所示:
:- use_module(library(clpfd)).
允许您使用transpose/2谓词,如下所示:
1 ?- transpose([[1,2,3],[4,5,6],[6,7,8]], X).
X = [[1, 4, 6], [2, 5, 7], [3, 6, 8]].
Run Code Online (Sandbox Code Playgroud)
否则(如果没有SWI-PROLOG),你可以简单地使用这个实现(在SWI的clpfd中碰巧是旧实现):
transpose([], []).
transpose([F|Fs], Ts) :-
transpose(F, [F|Fs], Ts).
transpose([], _, []).
transpose([_|Rs], Ms, [Ts|Tss]) :-
lists_firsts_rests(Ms, Ts, Ms1),
transpose(Rs, Ms1, Tss).
lists_firsts_rests([], [], []).
lists_firsts_rests([[F|Os]|Rest], [F|Fs], [Os|Oss]) :-
lists_firsts_rests(Rest, Fs, Oss).
Run Code Online (Sandbox Code Playgroud)
有关使用foldl和maplist内置函数的更新版本,请参阅clpfd.pl.
这是我能想到的最小的解决方案。
transpose([[]|_], []).
transpose(Matrix, [Row|Rows]) :- transpose_1st_col(Matrix, Row, RestMatrix),
transpose(RestMatrix, Rows).
transpose_1st_col([], [], []).
transpose_1st_col([[H|T]|Rows], [H|Hs], [T|Ts]) :- transpose_1st_col(Rows, Hs, Ts).
Run Code Online (Sandbox Code Playgroud)
:- transpose([[1,2,3],
[4,5,6],
[7,8,9]], R),
print(R).
Run Code Online (Sandbox Code Playgroud)
印刷品:
[[1,4,7],
[2,5,8],
[3,6,9]]
Run Code Online (Sandbox Code Playgroud)
它的工作方式是transpose将递归调用transpose_1st_col提取和转置矩阵的第一列。例如:
:- transpose_1st_col([[1,2,3],
[4,5,6],
[7,8,9]], Row, RestMatrix),
print(Row),
print(RestMatrix).
Run Code Online (Sandbox Code Playgroud)
将打印
[1,4,7]
Run Code Online (Sandbox Code Playgroud)
和
[[2,3],
[5,6],
[8,9]]
Run Code Online (Sandbox Code Playgroud)
重复此过程,直到输入矩阵为空为止,此时所有列都已转置。然后将转置的列合并到转置的矩阵中。