表示二维数组的最佳或最简单方法
Best or easiest way to represent 2D array
在 Prolog 中表示二维数组的最佳方式是什么?
这样我就可以通过 x,y 坐标 get/set 值。
列表列表看起来很麻烦!但如果没有现成的解决方案并且更容易实施...
红色,也许元组的元组可能更容易实现,因为 arg/setarg ?
这就是我到目前为止所得到的......只需要创建数组:
get(X,Y,Ary,Val) :-
arg(X,Ary,Row),
arg(Y,Row,Val).
set(X,Y,Ary,Val) :-
arg(X,Ary,Row),
setarg(Y,Row,Val).
不确定我是否可以跳过列表部分?
fill([], _, 0).
fill([X|Xs], X, N) :-
succ(N0, N),
fill(Xs, X, N0).
new_ary1d(Size,Sym,Ary) :-
fill(A,Sym,Size),
Ary =.. [a1 | A].
new_ary2d(Rows,Cols,Sym,Ary) :-
new_ary1d(Cols,Sym,A1),
fill(A2,A1,Rows),
Ary =.. [a2 | A2].
上面的列表转换没有正确工作,所以
使用@slago 模板我得到了 this
谢谢
我想你可以这样做:
matrix_new(Nrows, Ncols, Matrix) :-
length(Matrix, Nrows),
length(Row, Ncols),
maplist(=(0), Row),
maplist(=(Row), Matrix).
matrix_get(Matrix, I, J, Element) :-
nth1(I, Matrix, Row),
nth1(J, Row, Element).
matrix_set(Matrix, I, J, Element, NewMatrix) :-
nth1(I, Matrix, Row, RestOfMatrix),
nth1(J, Row, _, RestOfRow),
nth1(J, NewRow, Element, RestOfRow),
nth1(I, NewMatrix, NewRow, RestOfMatrix).
示例:
?- matrix_new(2,3,M0), matrix_set(M0,1,1,10,M1), matrix_set(M1,2,3,60,M2), matrix_get(M2,1,1,X11).
M0 = [[0, 0, 0], [0, 0, 0]],
M1 = [[10, 0, 0], [0, 0, 0]],
M2 = [[10, 0, 0], [0, 0, 60]],
X11 = 10.
编辑 不推荐 创建有副作用的谓词。无论如何,使用术语的可能解决方案如下:
m_new(Nrows, Ncols, Matrix) :-
functor(Matrix, array, Nrows),
functor(Row, array, Ncols),
forall(arg(J,Row,_), nb_setarg(J,Row,0)),
forall(arg(I,Matrix,_), nb_setarg(I,Matrix,Row)).
m_set(Matrix, I, J, Value) :-
arg(I, Matrix, Row),
setarg(J, Row, Value).
m_get(Matrix, I, J, Value) :-
arg(I, Matrix, Row),
arg(J, Row, Value).
示例:
?- m_new(2,3,M), m_set(M,1,1,9), m_set(M,2,3,8), m_get(M,1,1,X11), m_get(M,2,3,X23), m_get(M,1,2,X12).
M = array(array(9, 0, 0), array(0, 0, 8)),
X11 = 9,
X23 = 8,
X12 = 0.
在 Prolog 中表示二维数组的最佳方式是什么?
这样我就可以通过 x,y 坐标 get/set 值。
列表列表看起来很麻烦!但如果没有现成的解决方案并且更容易实施...
红色,也许元组的元组可能更容易实现,因为 arg/setarg ?
这就是我到目前为止所得到的......只需要创建数组:
get(X,Y,Ary,Val) :-
arg(X,Ary,Row),
arg(Y,Row,Val).
set(X,Y,Ary,Val) :-
arg(X,Ary,Row),
setarg(Y,Row,Val).
不确定我是否可以跳过列表部分?
fill([], _, 0).
fill([X|Xs], X, N) :-
succ(N0, N),
fill(Xs, X, N0).
new_ary1d(Size,Sym,Ary) :-
fill(A,Sym,Size),
Ary =.. [a1 | A].
new_ary2d(Rows,Cols,Sym,Ary) :-
new_ary1d(Cols,Sym,A1),
fill(A2,A1,Rows),
Ary =.. [a2 | A2].
上面的列表转换没有正确工作,所以 使用@slago 模板我得到了 this 谢谢
我想你可以这样做:
matrix_new(Nrows, Ncols, Matrix) :-
length(Matrix, Nrows),
length(Row, Ncols),
maplist(=(0), Row),
maplist(=(Row), Matrix).
matrix_get(Matrix, I, J, Element) :-
nth1(I, Matrix, Row),
nth1(J, Row, Element).
matrix_set(Matrix, I, J, Element, NewMatrix) :-
nth1(I, Matrix, Row, RestOfMatrix),
nth1(J, Row, _, RestOfRow),
nth1(J, NewRow, Element, RestOfRow),
nth1(I, NewMatrix, NewRow, RestOfMatrix).
示例:
?- matrix_new(2,3,M0), matrix_set(M0,1,1,10,M1), matrix_set(M1,2,3,60,M2), matrix_get(M2,1,1,X11).
M0 = [[0, 0, 0], [0, 0, 0]],
M1 = [[10, 0, 0], [0, 0, 0]],
M2 = [[10, 0, 0], [0, 0, 60]],
X11 = 10.
编辑 不推荐 创建有副作用的谓词。无论如何,使用术语的可能解决方案如下:
m_new(Nrows, Ncols, Matrix) :-
functor(Matrix, array, Nrows),
functor(Row, array, Ncols),
forall(arg(J,Row,_), nb_setarg(J,Row,0)),
forall(arg(I,Matrix,_), nb_setarg(I,Matrix,Row)).
m_set(Matrix, I, J, Value) :-
arg(I, Matrix, Row),
setarg(J, Row, Value).
m_get(Matrix, I, J, Value) :-
arg(I, Matrix, Row),
arg(J, Row, Value).
示例:
?- m_new(2,3,M), m_set(M,1,1,9), m_set(M,2,3,8), m_get(M,1,1,X11), m_get(M,2,3,X23), m_get(M,1,2,X12).
M = array(array(9, 0, 0), array(0, 0, 8)),
X11 = 9,
X23 = 8,
X12 = 0.