我开始玩prolog,并且在Java背景下对我来说真的很难,所以这里有一个愚蠢的问题:
你如何编写一个indexOf谓词,能够给出给定列表中给定元素的索引?
我的第一个问题是关于谓词arity:我想它应该是3,例如:
indexOf(List,Element, Index) :- ......
我是对的吗?可能这已经存在于内置库中,但我想学习如何编写它。谢谢你的帮助。
答案 0 :(得分:11)
你可以递归地做:假设从0开始的索引(否则只是在第一个子句中用0改变0)
indexOf([Element|_], Element, 0). % We found the element
indexOf([_|Tail], Element, Index):-
indexOf(Tail, Element, Index1), % Check in the tail of the list
Index is Index1+1. % and increment the resulting index
如果您只想找到第一个外观,可以添加剪切(!)以避免回溯。
indexOf([Element|_], Element, 0):- !.
indexOf([_|Tail], Element, Index):-
indexOf(Tail, Element, Index1),
!,
Index is Index1+1.
答案 1 :(得分:1)
应该更喜欢使用尾递归:
indexOf(V, [H|T], A, I)
:-
Value = H, A = I, !
;
ANew is A + 1,
indexOf(V, T, ANew, I)
.
indexOf(Value, List, Index)
:-
indexOf(Value, List, 0, Index)
.
indexOfWithoutFailure(Value, List, Index)
:-
indexOf(Value, List, 0, Index)
;
Index = -1
.
一些示例查询:
?- indexOf(d, [a, b, c, d, e, f], Index).
Index = 3.
?- indexOf(x, [a, b, c, d, e, f], Index).
false.
?- indexOfWithoutFailure(x, [a, b, c, d, e, f], Index).
Index = -1.
如果要获取列表中元素的所有索引,则应该为其编写另一个谓词,而不使用名为allIndexesOf的切割。
答案 2 :(得分:0)
我以后继符号表示,并且它非常简洁明了:
index([V|_],V,0).
index([_|T],V,s(I)) :- index(T,V,I).
样本输出:
?- index([a,b,c,a],a,X).
X = 0 ;
X = s(s(s(0))) ;
false.
?- index(List,a,s(0)).
List = [_G1710, a|_G1714].