因此,故事始于计算列表中元素的数量。
然后,当我在Internet上搜索解决方案时,我遇到了这段代码。
count([],0).
count([_HEAD|TAIL],X) :-
count(TAIL,X1),
X is X1+1.
但是,关于代码实际如何工作没有明确的解释,这就是为什么我在这里要求获得有关此代码的明确解释的原因。
希望有人能够一步一步解释,以便我能更好地理解。
答案 0 :(得分:2)
请以声明的方式思考。您将列表与其长度相关联,因此更好的关系名称为list_length/2
:第一个参数是列表,第二个参数是其长度。
显然,空列表[]
的长度为0。
此外,如果Tail
是长度为L0
的列表,则[_|Tail]
的长度为L0 + 1
。
答案 1 :(得分:2)
count([] ,0)
表示空列表包含0个元素。
现在,计算列表的元素
count([_HEAD|TAIL],X):-
% we remove the first element of the list
% we count the elements of the rest of the list
count(TAIL,X1),
% and we add 1 to the number of the elements of the rest
X is X1+1.
答案 2 :(得分:1)
学会递归思考很难。大多数递归问题可以分解为一些“特殊情况”和一般情况。在这种情况下,我们有两种情况:
空列表。这是我们的特殊情况。空列表的长度始终为零。
非空列表。这是我们的一般情况。我们有列表的 head (单个项目)和它的 tail (列表的其余部分:零个或多个项目)。所以,我们可以说非空列表的长度是 tail 的长度加上1( head )。
Prolog让你只需声明这些就是定义真理的事实。然后我们让Prolog推理引擎确定断言的真实性或虚假性。致白:
count( [] , 0 ) . % The count of an empty list is zero
count( [_|Xs] , N ) :- % If the list is non-empty,
count( Xs, T ) , % - we count its tail as T
N is T+1 % - and then add 1.
. %
然后......你可以这样说:
?- count([],3).
false.
?- count([a,b,c],3).
true.
这也适用于生成方式:
?- count( List , 3 ) .
List = [_G938, _G941, _G944] .
甚至......
?- count(X,N).
X = [], N = 0 ;
X = [_G950], N = 1 ;
X = [_G950, _G953], N = 2 ;
X = [_G950, _G953, _G956], N = 3 ;
...
请注意,这不是尾递归的,并且提供足够长度的列表,最终将溢出其堆栈。
您也可以以尾递归的方式编写它,这可能更容易理解:
count( Xs , N ) :- % to count the number of items in a list,
count( Xs , 0 , N ) % - invoke the helper, seeding the accumulator with 0.
. %
count( [] , N , N ) . % if the source list is empty, the accumulator contains the number of items in the list.
count( [_|Xs] , T , N ) :- % otherwise (source list is non-empty)
T1 is T+1 , % - increment the accumulator, and
count(Xs,T1,N) % - recurse down on the tail, passing the incremented accumulator
. %