我如何n*n在Prolog中获得一个大小矩阵的对角线列表?
预期行为:
?- diagonal1([[1,3,2],[4,5,7],[6,8,9]],D1).
D1=[1,5,9]
?- diagonal2([[1,3,2],[4,5,7],[6,8,9]],D2).
D2=[2,5,6].
Run Code Online (Sandbox Code Playgroud)
(我使用内置函数很好.)
这是我的解决方案foldl/4:
extract_element(L, L1, [H|L1]):-
length(L1, N1),
length(L2, N1),
append(L2, [H|_], L).
diagonal1(In, Out):-
foldl(extract_element, In, [], Res),
reverse(Res,Out).
diagonal2(In, Out):-
reverse(In, In2),
foldl(extract_element, In2, [], Out).
Run Code Online (Sandbox Code Playgroud)
你可以看到在现货的差异diagonal1/2和diagnal2/2实现?
在diagonal1/2我们foldl/4以相反的顺序返回Res变量中的结果表单所需的顺序,因此我们反转结果以获得正确的列表.另一方面,diagonal2/2你foldl/4通过反转输入列表来理解上面的工作方式,我们不仅能够提取正确的元素,而且现在返回的逆序foldl/4是正确的!
例:
?- diagonal1([[1,3,2],[4,5,7],[6,8,9]],D1).
D1 = [1, 5, 9].
?- diagonal2([[1,3,2],[4,5,7],[6,8,9]],D2).
D2 = [2, 5, 6].
Run Code Online (Sandbox Code Playgroud)
list_diag1([], []).
list_diag1([[E|_]|Ess], [E|Ds]) :-
maplist(list_tail, Ess, Ess0),
list_diag1(Ess0, Ds).
list_tail([_|Es], Es).
list_diag2(Ess,Ds) :-
maplist(reverse, Ess, Fss),
list_diag1(Fss, Ds).
Run Code Online (Sandbox Code Playgroud)
示例查询:
?- list_diag1([[a,b,c],[d,e,f],[g,h,i]], D1).
D1 = [a,e,i].
?- list_diag2([[a,b,c],[d,e,f],[g,h,i]], D2).
D2 = [c,e,g].
Run Code Online (Sandbox Code Playgroud)