我有一个列表L = [[5,6,7,8],[10,11,12,13],[1,2,3,4],[14,15,16,17]]
Ii。这代表了我的矩阵。大小可以改变动态,因此块大小可以不同,4x4 = 4个元素,9x9 = 9个元素
我想获得组成List的4个方格。(在这种情况下,它是4乘4的矩阵)。如果我有那个矩阵:
5 6 7 8
10 11 12 13
1 2 3 4
14 15 16 17
结果应为:
R = [5,6,10,11],[7,8,12,13],[1,2,14,15],[3,4,16,17].
欢迎任何建议。谢谢
答案 0 :(得分:1)
您需要的第一件事就是将列表列表转换为矩阵的杠杆。什么区分二维矩阵与列表列表?坐标系的想法。因此,您需要一种方法将坐标对与矩阵中的相应值相关联。
at(Matrix, X, Y, V) :- nth0(X, Matrix, Row), nth0(Y, Row, V).
这个谓词可以在(X,Y)处索引矩阵并得到值V.这就是IMO,它是Prolog强大之处的大量演示,因为一旦你有了这个,简单的谓词,你获得:
在提供的点获取值的能力:
?- at([[5,6,7,8],[10,11,12,13],[1,2,3,4],[14,15,16,17]], 1,3, V).
V = 13.
迭代整个矩阵的能力(仅实例化Matrix
并将其他参数保留为变量):
?- at([[5,6,7,8],[10,11,12,13],[1,2,3,4],[14,15,16,17]], X,Y, V).
X = Y, Y = 0,
V = 5 ;
X = 0,
Y = 1,
V = 6 ;
...
X = 3,
Y = 2,
V = 16 ;
X = Y, Y = 3,
V = 17.
搜索矩阵中值的功能:
?- at([[5,6,7,8],[10,11,12,13],[1,2,3,4],[14,15,16,17]], X,Y, 14).
X = 3,
Y = 0 ;
false.
所以这是一个非常有用的杠杆!在传统的语言中,你需要三个不同的函数来完成所有这些事情,但这是不同的,因为在Prolog中我们只需要在事物之间定义关系(在这种情况下,数据结构)和一个坐标对)和Prolog可以做很多繁重的工作。
现在很容易看到我们如何通过定义我们希望看到的X和Y值的集合来生成特定的子矩阵。例如,要获得左上角矩阵,我们会这样做:
?- between(0,1,X), between(0,1,Y),
at([[5,6,7,8],[10,11,12,13],[1,2,3,4],[14,15,16,17]], X,Y, V).
X = Y, Y = 0,
V = 5 ;
X = 0,
Y = 1,
V = 6 ;
X = 1,
Y = 0,
V = 10 ;
X = Y, Y = 1,
V = 11.
我们当然可以使用findall/3
在一个地方收集解决方案:
?- findall(V, (between(0,1,X), between(0,1,Y),
at([[5,6,7,8],[10,11,12,13],[1,2,3,4],[14,15,16,17]], X,Y, V)),
Vs).
Vs = [5, 6, 10, 11].
你的问题还剩下一些算法。让我们看看我们是否有一个方阵:
square_matrix(M, Degree) :-
length(M, Degree),
maplist(length, M, InnerDegrees),
forall(member(I, InnerDegrees), I=Degree).
这不是一个完美的谓词,因为它不会产生!但是它会告诉我们矩阵是否是正方形,如果是,它有多大程度:
?- square_matrix([[5,6,7,8],[10,11,12,13],[1,2,3,4],[14,15,16,17]], D).
D = 4.
一旦你拥有了,你需要做的就是公式化:
maplist/N
就足够了。希望这有帮助!