2014-10-06 58 views
2

我的任务是这样的:编写一个读取整数x和整数列表L;然后将x所有位置的列表定位到L,并返回结果列表。例如,对于x=2L=[1,2,3,4,2,5,2,6]程序应返回列表R=[2,5,7]在Prolog中查找列表中的值的所有位置

到目前为止,我已经能够写一个indexOf谓:

indexOf([E|_], E, 1). 
indexOf([_|T], E, I) :- indexOf(T, E, I2), I is I2 + 1. 

然而,这并不能“回归”的列表。所以:

indexOf([a,b,c,a,d], a, R). 
R = 1; 
R = 4 

我想要做这样的事情:

findAll([a,b,c,a,d], a, R). 
R = [1, 4] 

但我不知道如何收集值成一个列表。

这是一个学校作业,所以我只想欣赏一下正确的方向。

回答

1

微调:你找到指数,但你不收集它们。

indices(List, E, Is) :- 
    indices_1(List, E, Is, 1). 

对于空表,索引列表是空的, 和元素不要紧

indices_1([], _, [], _). 

如果该元素是一样的头,收集指标。

indices_1([E|Xs], E, [I|Is], I) :- 
    I1 is I + 1, 
    indices_1(Xs, E, Is, I1). 

这需要另一个条款才能正常工作。

编辑:

一种方式做到这一点是:

indices_1([X|Xs], E, Is, I) :- dif(X, E), 
    I1 is I + 1, 
    indices_1(Xs, E, Is, I1). 

在前款规定,在名单的头和元素是统一的。在这个条款中,它们明显不同。这意味着对于第一个参数列表中的一个元素,这两个子句中只有一个可以为真。

编辑:

另一种方法是使用findallnth1

indices(List, E, Is) :- 
    findall(N, nth1(N, List, E), Is). 
+0

谢谢!我添加了这个子句:'indices_1([_ | T],E,Is,I): - I1是I + 1,indices_1(T,E,Is,I1)。' – 2014-10-06 19:52:30

+0

您的解决方案只返回完整列表(例如'R = 1,3]'),而我的每一步都返回它(例如'R = [1,3]; R = [1]; R = [3],R = []')。为什么会这样呢? – 2014-10-06 20:10:13

+0

@AndrewBurgess查看我的编辑 – 2014-10-06 20:30:12