list - 计算相同的元素序言

标签 list prolog

我想对列表中的一个元素进行计数,并在不同元素出现的地方停止计数,并跳转到下一个相同的元素。

答案应该是这样的:

?- count(a,[a,a,a,a,b,a,a,a],X).
X = [4,3]

?- count(a,[a,a,a,b,a,b,a,a,b,a,a,a,a],X).
X = [3,1,2,4]

我为 count/3 写的代码是:

count(_, [], []).
count(X, [X | T], N) :-
   count(X, T, N1),
   !, 
   N is N1 + 1.
count(X, [_ | T], N) :-
   count(X, T, N).

我不知道如何让它返回一个数字列表。 谁能帮我? 谢谢。

最佳答案

以下是您如何做到这一点并保留 !

在下文中,我们使用元谓词 ( splitlistIfAdj/3 , tfilter/3 , 和 maplist/3 ) 和具体化的等式/不等式谓词( (=)/3dif/3 )。

让我们取 E = aXs0 = [a,a,a,b,a,b,a,a,b,a,a,a,a] 并逐步构建 count/3:

  1. 首先,让 Xs1 包含 Xs0 中项目的运行:

    ?- Xs0 = [a,a,a,b,a,b,a,a,b,a,a,a,a], splitlistIfAdj(dif,Xs0,Xs1).
    Xs0 = [ a,a,a,  b,  a,  b,  a,a,  b,  a,a,a,a ],
    Xs1 = [[a,a,a],[b],[a],[b],[a,a],[b],[a,a,a,a]].
    

  2. The list of runs Xs1 contains all runs. Let Xs2 contain only the ones we are interested in:

    ?- Xs1 = [[a,a,a],[b],[a],[b],[a,a],[b],[a,a,a,a]], tfilter(\[X|_]^(X=a),Xs1,Xs2).
    Xs1 = [[a,a,a],[b],[a],[b],[a,a],[b],[a,a,a,a]],
    Xs2 = [[a,a,a],    [a],    [a,a],    [a,a,a,a]].
    

  3. Almost done! At last, we map Xs2 (a list of E-runs) to the respective run lengths Xs:

    ?- Xs2 = [[a,a,a],[a],[a,a],[a,a,a,a]], maplist(length,Xs2,Xs).
    Xs2 = [[a,a,a],[a],[a,a],[a,a,a,a]],
    Xs  = [      3,  1,    2,        4].
    

Now, let's put it all together!

count(E,Xs0,Xs) :-
    splitlistIfAdj(dif,Xs0,Xs1),
    tfilter(E+\[X|_]^(X=E),Xs1,Xs2),   % works for _any_ item E
    maplist(length,Xs2,Xs).

Let's run some queries:

?- count(a,[a,a,a,a,b,a,a,a],Xs).
Xs = [4,3].                            % succeeds deterministically
?- count(a,[a,a,a,b,a,b,a,a,b,a,a,a,a],Xs).
Xs = [3,1,2,4].                        % succeeds deterministically

由于代码单调,对于更一般的查询,我们也能得到逻辑上合理的答案:

?- count(E,[a,a,a,b,a,b,a,a,b,a,a,a,a],Xs).
Xs = [3,1,2,4], E = a              ;
Xs = [1,1,1],   E = b              ;
Xs = [],        dif(E,a), dif(E,b) .

关于list - 计算相同的元素序言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26417484/

相关文章:

c# - 嵌套列表中的不同项

java - 将 List<Son> 转换为 List<Father>

Prolog:识别 n >= 1 的 a^n b^(n+1) 语言

prolog - 哪种存储事实的方式,apple vs exists(apple) 更符合习惯?

python - 如何计算数据集的元素由列表组成

list - 将新项目附加到方案中列表的末尾

list - 将 foldl 写为 foldr 混淆

prolog - 序言中的霍恩条款

Prolog 回溯寻找解决方案并返回错误

prolog - 如何使用成员谓词在序言中指定约束