我试图从行列表(X)中提取索引(K)的某个列(COLUMN)。
这是我到目前为止编写的代码:
extract(K,X,COLUMN):-
constructColumn(K,1,X,COLUMN).
constructColumn(K,B,X,COLUMN):-
nth1(B,X,LINE),
nth1(K,LINE,ELEMENTCOLUMN),
incr(B,B1),
constructColumn(K,B1,X,ELEMENTCOLUMN|COLUMN);
!.
incr(X, X1) :- X1 is X+1.
当我追踪它的运作方式时,我发现我正在构建的新COLUMN列表不会在结尾处作为输出提供,它只输出true。有没有办法以类似的方式向谓词添加元素?
答案 0 :(得分:2)
maplist/3
谓词在这里也运作良好。 maplist
将谓词应用于一组列表参数,从而产生其他列表参数,其中该谓词用于处理一个参数。
因此,您可以将extract/3
写为:
extract(ColNumber, Matrix, Column) :-
maplist(nth0(ColNumber), Matrix, Column).
你已经完成了。 :)
| ?- extract(2, [[a,b,c,d],[e,f,g,h],[i,j,k,l]], R).
R = [c,g,k]
yes
| ?-
答案 1 :(得分:0)
由于你有很多次迭代,你可以使用findall/3
谓词跳过大部分的写作:
extract(K,X,COLUMN):- findall(Elem , (member(X1,X), nth0(K,X1,Elem)) , COLUMN).
上面做的是每个X1行(X行的成员)采用Kth元素(使用nth0/3
谓词)并将其存储到COLUMN列表。
您可以在此处阅读findall/3
:www.swi-prolog.org/pldoc/man?predicate=findall/3
示例:
?- extract(1,[[1,2,3,4],[11,22,33,44],[111,222,333,444]],COLUMN).
COLUMN = [2, 22, 222].
?- extract(0,[[1,2,3,4],[11,22,33,44],[111,222,333,444]],COLUMN).
COLUMN = [1, 11, 111].
?- extract(2,[[1,2,3,4],[11,22,33,44],[111,222,333,444]],COLUMN).
COLUMN = [3, 33, 333].
?- extract(3,[[1,2,3,4],[11,22,33,44],[111,222,333,444]],COLUMN).
COLUMN = [4, 44, 444].
?- extract(5,[[1,2,3,4],[11,22,33,44],[111,222,333,444]],COLUMN).
COLUMN = [].
答案 2 :(得分:0)
只是为了显示使代码正常工作所需的修改:
extract(K,X,COLUMN):-
constructColumn(K,1,X,COLUMN).
constructColumn(K,B,X,[ELEMENTCOLUMN|COLUMN]):-
nth1(B,X,LINE),
nth1(K,LINE,ELEMENTCOLUMN),
succ(B,B1),
!,
constructColumn(K,B1,X,COLUMN).
constructColumn(_K,_B,_X,[]).
让我们解释一下:我们使用nth1(B,X,LINE)
来访问每一行,当它失败时,我们就完成了。第一个改进可能是通过索引删除对行的访问:只需让列表(列表)控制递归:
extract(_,[],[]).
extract(K,[LINE|LINES],[ELEMENTCOLUMN|COLUMN]):-
nth1(K,LINE,ELEMENTCOLUMN),
extract(K,LINES,COLUMN).
好多了,不是吗?