如何跳过已经打印过prolog的元素

时间:2014-06-13 14:21:47

标签: prolog prolog-dif

我试图像这样在Prolog中进行练习:我引入这个列表[10,20, 10, 20, 30],程序显示:

10 - 2 time; 20 - 2 times; 30 - 1 times.

这是我的代码:

conta(_,[], 0).
conta(X, [X|T], N) :-   conta(X,T, N2), N is N2 + 1 . 
conta(X, [Y|T], N) :-  X \= Y,   conta(X,T,N).  

aux([],[]).
aux([X|L],L1):-conta(X,L1,C),write(X),write(C), write('vezes'),aux(L,L1).

但结果如下:

10 - 2times  20 -2time 10-2times 20-2times 30-1 time
false.

他向元素显示元素在列表中的时间。 任何帮助,请!!

1 个答案:

答案 0 :(得分:1)

在你的问题陈述中,你将纯粹的关系与副作用散布在一起。虽然您可以通过这种方式解决问题,但您只会看到很少有Prolog的有趣属性。相反,尝试将您的问题表述为纯粹的关系。所以想象一下,你已经实现了它,并为它制定了一些查询:

?- list_vezes([10,20, 10, 20, 30], [10-2,20-2,30-1]).
true.

以下解决方案计算并删除相应的元素。它有一些n 2 运行时。

list_vezes([], []).
list_vezes([E|Es1], [E-N|Vezes]) :-
   n_occ(E, Es1,Es2, 1,N),
   list_vezes(Es2, Vezes).

n_occ(_, [],[], N,N).
n_occ(E, [E|Es0],Es, N0,N) :-
   N1 is N0+1,
   n_occ(E, Es0,Es, N1,N).
n_occ(E, [F|Es0],[F|Es], N0,N) :-
   dif(F,E),
   n_occ(E, Es0,Es, N0,N).

在许多Prolog系统中,是内置的。如果您没有该链接,请参阅该链接。

现在,如果您仍想打印出您所说的文字,可以使用以下新列表执行此操作:

printitem(E-N) :-
   writeq(E-N), write(' times\n').


compter_et_imprimer(L) :-
   list_vezes(L, Vezes),
   maplist(printitem, Vezes).