list - Prolog - 返回矩阵的第 n 行

标签 list matrix prolog counter

我正在尝试编写谓词 rowN/3它返回矩阵的第 n 个元素(在本例中为行)。
例子:

?- rowN([[1,2],[3,4],[5,6]], 2, R). 
R = [3,4];
No

我在柜台上挣扎。我试图找到一些非常相似的例子,但没有成功。到目前为止,我已经设法写了这个:

代码:
rowN(L,[],[]).
rowN([],X,[]).
rowN([],[],[].
rowN([H|T],X,R) :-
    A==X,
    A is A + 1,
    rowI(T,A,H).

最佳答案

这一行没有多大意义:

rowN(L,[],[]).

因为第二个参数是一个整数(如果我理解正确的话),你使用一个列表。几乎所有的论点都是这种情况。此外,您使用 RowI在你的递归调用中?

解决方案

一种解决方案是首先指定第一行 ( I = 1 ) 等于矩阵的头:
rowN([H|_],1,H).

接下来,您需要找到一种迭代方式来枚举您的矩阵。所以标题绝对是以下形式:
rowN([H|T],I,X) :-
#   ...

现在我们假设 I不等于 1 (我们稍后会讨论这个话题)。在这种情况下,我们需要进一步遍历矩阵,因此我们将取尾部并设置计数器 I一回。这可以使用:
rowN([_|T],I,X) :-
    I1 is I-1,
    rowN(T,I1,X).

所以我们的谓词是:
rowN([H|_],1,H).
rowN([_|T],I,X) :-
    I1 is I-1,
    rowN(T,I1,X).

现在,如果您使用此谓词,它将给出正确的结果:
?- rowN([[1,2],[3,4],[5,6]], 2, R).
R = [3, 4] ;
false.

问题是为什么谓词不生成其他结果:显示第一个结果后,对于rowN([[1,2],[3,4],[5,6]], 2, R) :- rowN([[3,4],[5,6]],1,[3,4]). ,它可以尝试寻找替代品。它通过使用第二个子句来实现,但是它最终会用完行并调用 rowN([],_,_)谓词,由于没有匹配的子句,它将失败。

这个解决方案并不完美:它不能在所有方向上都正确工作,这在 Prolog 中通常很难。这就是优秀的 Prolog 程序员编写库的原因。

使用 的内置 nth1/3
您可以使用 nth1/3 而不是重新发明轮子swi-prolog 中的谓词。尽管参数交换了 - 您需要像 nth1(2,[[1,2],[3,4],[5,6]],R). 一样调用它- 它的优点是它可以在更多方向上工作,大多数人可以在一个快速解决方案中找到它,几乎可以肯定它没有错误(因为它已经被所有使用谓词的 Prolog 程序测试了数十亿次)和一些这些内置函数是用 C++ 实现的,因此有时会更快。例如:
?- nth1(2, [[1,2],[3,4],[5,6]], R).
R = [3, 4].

?- nth1(I, [[1,2],[3,4],[5,6]], [5,6]).
I = 3.

?- nth1(I, [[1,2],[3,4],[5,6]], R).
I = 1,
R = [1, 2] ;
I = 2,
R = [3, 4] ;
I = 3,
R = [5, 6].

?- nth1(I,M,[2,3]).
I = 1,
M = [[2, 3]|_G23] ;
I = 2,
M = [_G22, [2, 3]|_G26] ;
I = 3,
M = [_G22, _G25, [2, 3]|_G29] ;
I = 4,
M = [_G22, _G25, _G28, [2, 3]|_G32] .

因此你可以问第二行是什么,问行在哪里[5,6]定位,通过使用索引的元组 I 来回答,使查询更加通用和行 R并生成一个矩阵 [2,3]某处。

关于list - Prolog - 返回矩阵的第 n 行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34167214/

相关文章:

prolog - 在 Prolog 中选择独特的元素

prolog - 在Prolog中计算数字是否为质数

python - 在 Python 中预分配或不预分配列表

c# - 将属性添加到列表?

algorithm - 具有排序行的矩阵的中值

algorithm - 具有相同整数的最大子矩阵

r - 使用 R 创建完整的双列

Prolog - 通过让步获得不同的结果

python - 用 Python 中的另一个列表刷新列表内容

javascript - 使用 jquery 向上移动列表项