prolog - 在 Prolog 中复制 findall
问题描述
我试图让一些代码返回一个位置/索引列表,其中元素在某个基本列表中找到。经过大量搜索、复制、调整等。以下代码是我到目前为止所得到的。
它可以在 SWISH 中使用,但需要我点击下几次才能最终获得一个包含搜索元素所有位置的列表。
在发送/打印回结果列表之前,我如何让它完成所有答案?
pos([E|_],E,I,P) :- P = I.
pos([E|T],E,I,[P|Pt]) :- I1 is I+1, pos(T,E,I1,Pr), Pt = Pr, P = I.
pos([H|T],E,I,P) :- H\=E, I1 is I+1, pos(T,E,I1,Pr), P = Pr.
find(X,P):- a(L),pos(L,X,1,Pr), P = Pr.
a([2,1,4,5,3,2,6,2,1,21,2,1,4,7,4,3,5,2,4,6,8,2,1,37,3,2]).
结果:
?- find(2,X)
X = 1
X = [1|6]
X = [1, 6|8]
X = [1, 6, 8|11]
X = [1, 6, 8, 11|18]
X = [1, 6, 8, 11, 18|22]
X = [1, 6, 8, 11, 18, 22|26]
解决方案
有几种可能的解决方案。如果你想保留你的代码,你应该写这样的东西(基本上,你确实需要在找到匹配项时再次调用谓词)
find_in([],_,_,[]).
find_in([El|TL],El,Pos,[Pos|T]):- !,
P1 is Pos + 1,
find_in(TL,El,P1,T).
find_in([_|T],El,Pos,L):-
P1 is Pos + 1,
find_in(T,El,P1,L).
find_pos(El,LPos):-
a(L),
find_in(L,El,1,LPos).
?- find_pos(2,X).
X = [1, 6, 8, 11, 18, 22, 26]
我已经使用了切割,但你可以避免使用它\=
(就像你在你的问题中所做的那样)。如果您可以使用内置谓词(nth0/3
或类似的东西 and findall/3
),有一个更紧凑的解决方案:
find_pos(El,LPos):-
a(L),
findall(I,nth1(I,L,El),LPos).
?- find_pos(2,X).
X = [1, 6, 8, 11, 18, 22, 26]
推荐阅读
- git - git 中是否有可能只忽略文件中的特定更改,例如数字?
- angular - 当资源部件发生变化时如何停止自动重新加载?
- c++ - c++ 将 typedef 与 LegacyRandomAccessIterator 一起使用
- dax - DAX-如何实现每个类别的年初至今?
- android - 如何将我的 Android 应用程序与 mongodb.atlas 连接?
- android - 如何为 App Store 添加关联域?- 用于 App Store Connect 的 app-ads.txt 文件
- rpm-spec - 如何在 rpm 规范中自动创建许多子包
- android - 我得到了 java.lang.IllegalStateException: 更新 androidX 库时没有活动错误
- java - 反向单链表
- amazon-web-services - Alexa 请求客户联系访问被拒绝