Prolog:给定矩阵创建转置
Prolog: Given a Matrix create the transpose
我正在努力学习如何使用 Prolog。
我有一个矩阵,我应该对这个矩阵进行转置。
我这样做过:
transpose_matrix([], []).
transpose_matrix(Matrix, New_Matrix):-
length(Matrix, Num_Rows),
nth0(0, Matrix, First_Row),
length(First_Row, Num_Cols),
Num_Rows == Num_Cols,
transpose_matrix(Matrix, Num_Rows, 0, 0, New_Matrix).
transpose_matrix(Matrix, Num_Rows, Row, Col, [[Element|Rest]|Rest1]):-
Row < Num_Rows,
nth0(Row,Matrix,Current_Row),
nth0(Col,Current_Row,Element),
Row1 is Row + 1,
transpose_matrix(Matrix, Num_Rows, Row1, Col, [Rest|Rest1]).
transpose_matrix(Matrix, Num_Rows, Row, Col, [[_Element|_Rest]|Rest1]):-
Row >= Num_Rows,
Col1 is Col + 1,
transpose_matrix(Matrix, Num_Rows, 0, Col1, Rest1).
transpose_matrix(_Matrix, Num_Rows, _Row, Col, _New_Matrix):-
Col == Num_Rows.
以这种方式,当我将 1 加到 Row 上以选择正确的元素时,当 Row 等于 Length 时,我更新 Col 并将行值设置为 0。
现在这个方法似乎行得通了,我的问题是这些值是如何打印的:
transpose_matrix([[6, 3, 2], [8, 1, 4], [3, 5, 9]], New_Matrix).
New_Matrix = [[6, 8, 3, _17602|_17604], [3, 1, 5, _17650|_17652], [2, 4, 9, _17698|_17700]|_17658]
如何删除:
_17602| _17604...._17650|_17652..._17698|_17700]|_17658 ?
谢谢。
这可能对您有所帮助:
1- transp 谓词将采用任意长度的矩阵,并在 MatrixOut 中给出转置列表。
2- add_col 谓词可以让您免于 -1708,... 类型值的麻烦。
% transp(MatrixIn,MatrixOut)
transp([],[]).
transp([Row|Rows],Transpose) :-
transp(Rows,RowsT),
add_col(Row,RowsT,Transpose).
% add_col(Col,MatrixIn,MatrixOut)
add_col([],_,[]) :- !.
add_col([X|Col],[],[[X]|Rows]) :- !,
add_col(Col,[],Rows).
add_col([X|Col],[Row|Rows],[NewRow|NewRows]) :-
NewRow = [X|Row],
add_col(Col,Rows,NewRows).
示例:
?-transp([[2,0,1],[3,4,5],[6,7,8]],Out)
Out = [[2, 3, 6], [0, 4, 7], [1, 5, 8]]
?-transp([[6, 3, 2], [8, 1, 4], [3, 5, 9]],Out)
Out = [[6, 8, 3], [3, 1, 5], [2, 4, 9]]
?-transp([[6, 3, 2, 5, 3, 2], [8, 1, 4, 7, 4, 2], [3, 5, 9, 8, 5, 4],[6, 4, 5, 7, 8, 9]],Out)
Out = [[6, 8, 3, 6], [3, 1, 5, 4], [2, 4, 9, 5], [5, 7, 8, 7], [3, 4, 5, 8], [2, 2, 4, 9]]
注:解法来自我老师的Lecture
一个非常简洁的解决方案是:
transpose(Matrix, NewMatrix) :-
nonvar(Matrix),
findall(Row, maplist(nth1(_), Matrix, Row), NewMatrix).
这里有一些例子:
?- transpose([[1,2], [3,4]], M).
M = [[1, 3], [2, 4]].
?- transpose([[6,3,2], [8,1,4], [3,5,9]], Matrix).
Matrix = [[6, 8, 3], [3, 1, 5], [2, 4, 9]].
?- transpose([[1,2,3], [4,5,6], [7,8,9]], M), maplist(writeln,M).
[1,4,7]
[2,5,8]
[3,6,9]
M = [[1, 4, 7], [2, 5, 8], [3, 6, 9]].
工作原理:
nth1/3
生成元素(通过回溯)。
maplist/3
生成行(通过回溯)。
findall/3
收集所有行。
我正在努力学习如何使用 Prolog。
我有一个矩阵,我应该对这个矩阵进行转置。
我这样做过:
transpose_matrix([], []).
transpose_matrix(Matrix, New_Matrix):-
length(Matrix, Num_Rows),
nth0(0, Matrix, First_Row),
length(First_Row, Num_Cols),
Num_Rows == Num_Cols,
transpose_matrix(Matrix, Num_Rows, 0, 0, New_Matrix).
transpose_matrix(Matrix, Num_Rows, Row, Col, [[Element|Rest]|Rest1]):-
Row < Num_Rows,
nth0(Row,Matrix,Current_Row),
nth0(Col,Current_Row,Element),
Row1 is Row + 1,
transpose_matrix(Matrix, Num_Rows, Row1, Col, [Rest|Rest1]).
transpose_matrix(Matrix, Num_Rows, Row, Col, [[_Element|_Rest]|Rest1]):-
Row >= Num_Rows,
Col1 is Col + 1,
transpose_matrix(Matrix, Num_Rows, 0, Col1, Rest1).
transpose_matrix(_Matrix, Num_Rows, _Row, Col, _New_Matrix):-
Col == Num_Rows.
以这种方式,当我将 1 加到 Row 上以选择正确的元素时,当 Row 等于 Length 时,我更新 Col 并将行值设置为 0。
现在这个方法似乎行得通了,我的问题是这些值是如何打印的:
transpose_matrix([[6, 3, 2], [8, 1, 4], [3, 5, 9]], New_Matrix).
New_Matrix = [[6, 8, 3, _17602|_17604], [3, 1, 5, _17650|_17652], [2, 4, 9, _17698|_17700]|_17658]
如何删除:
_17602| _17604...._17650|_17652..._17698|_17700]|_17658 ?
谢谢。
这可能对您有所帮助:
1- transp 谓词将采用任意长度的矩阵,并在 MatrixOut 中给出转置列表。
2- add_col 谓词可以让您免于 -1708,... 类型值的麻烦。
% transp(MatrixIn,MatrixOut)
transp([],[]).
transp([Row|Rows],Transpose) :-
transp(Rows,RowsT),
add_col(Row,RowsT,Transpose).
% add_col(Col,MatrixIn,MatrixOut)
add_col([],_,[]) :- !.
add_col([X|Col],[],[[X]|Rows]) :- !,
add_col(Col,[],Rows).
add_col([X|Col],[Row|Rows],[NewRow|NewRows]) :-
NewRow = [X|Row],
add_col(Col,Rows,NewRows).
示例:
?-transp([[2,0,1],[3,4,5],[6,7,8]],Out)
Out = [[2, 3, 6], [0, 4, 7], [1, 5, 8]]
?-transp([[6, 3, 2], [8, 1, 4], [3, 5, 9]],Out)
Out = [[6, 8, 3], [3, 1, 5], [2, 4, 9]]
?-transp([[6, 3, 2, 5, 3, 2], [8, 1, 4, 7, 4, 2], [3, 5, 9, 8, 5, 4],[6, 4, 5, 7, 8, 9]],Out)
Out = [[6, 8, 3, 6], [3, 1, 5, 4], [2, 4, 9, 5], [5, 7, 8, 7], [3, 4, 5, 8], [2, 2, 4, 9]]
注:解法来自我老师的Lecture
一个非常简洁的解决方案是:
transpose(Matrix, NewMatrix) :-
nonvar(Matrix),
findall(Row, maplist(nth1(_), Matrix, Row), NewMatrix).
这里有一些例子:
?- transpose([[1,2], [3,4]], M).
M = [[1, 3], [2, 4]].
?- transpose([[6,3,2], [8,1,4], [3,5,9]], Matrix).
Matrix = [[6, 8, 3], [3, 1, 5], [2, 4, 9]].
?- transpose([[1,2,3], [4,5,6], [7,8,9]], M), maplist(writeln,M).
[1,4,7]
[2,5,8]
[3,6,9]
M = [[1, 4, 7], [2, 5, 8], [3, 6, 9]].
工作原理:
nth1/3
生成元素(通过回溯)。maplist/3
生成行(通过回溯)。findall/3
收集所有行。