【问题标题】:Prolog: Given a Matrix create the transposeProlog:给定一个矩阵创建转置
【发布时间】:2021-01-16 01:35:04
【问题描述】:

我正在尝试学习如何使用 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 ?

谢谢。

【问题讨论】:

    标签: prolog


    【解决方案1】:

    这可能会对您有所帮助:

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

    注意:解决方案来自我老师的讲座。

    【讨论】:

      【解决方案2】:

      一个非常简洁的解决方案是:

      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 收集所有行。

      【讨论】:

      • 不错的解决方案!
      猜你喜欢
      • 1970-01-01
      • 2011-05-15
      • 1970-01-01
      • 2022-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-16
      相关资源
      最近更新 更多