如何计算列表中元素的索引?

时间:2010-12-07 19:11:07

标签: prolog

我开始玩prolog,并且在Java背景下对我来说真的很难,所以这里有一个愚蠢的问题:

你如何编写一个indexOf谓词,能够给出给定列表中给定元素的索引?

我的第一个问题是关于谓词arity:我想它应该是3,例如:

indexOf(List,Element, Index) :- ......

我是对的吗?可能这已经存在于内置库中,但我想学习如何编写它。谢谢你的帮助。

3 个答案:

答案 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].