如何计算一个字符出现在Prolog的字符串列表中的次数?

时间:2012-12-17 15:57:08

标签: prolog

我想检查字符串中是否存在字符。所以Atom是字符串,Ch是字符。 name是一个谓词,它根据ASCII码转换数字列表中的字符串。

find_element是一个谓词,只有当元素X是列表的一部分时才应该为真。 C是一个计数器,告诉我们确切找到了元素X的位置。

这是我得到的结果:

?- exists(prolog,g). [103][112,114,111,108,111,103] false.

-------> 103是字母“g”的ASCII码,列表[112,114,111,108,111,103]是表示字符串“prolog”的列表。问题exists(prolog,g)应该提供真实的回应。

find_element谓词工作正常。我不明白为什么会发生这种情况,因为当我输入例如

?- find_element(5,[3,4,5,6,5,2],X).

我得到了X= 3 ; X = 5 ; false.  ---->

这绝对没问题,因为它告诉我5是列表的第3和第5个元素。

所以问题是当我输入find_element之类的内容时?- find_element(5,[3,4,5,6,5,2],X)正在工作,但当我尝试调用谓词存在时(调用find_element)时,问题就不行了。

这是代码:

find_element(X,[X|T],1).

find_element(X,[H|T],C):- find_element(X,T,TEMPC), C is TEMPC +1.

exists(Atom,Ch):- name(Atom,[X|T]), name(Ch,Z), write(Z), write([X|T]), find_element(Z,[X|T],Count).

提前致谢

1 个答案:

答案 0 :(得分:2)

我已经清理了一下你的代码,并修复了一个错误:

find_element(X,[X|_], 1).
find_element(X,[_|T], C) :-
    find_element(X,T,TEMPC),
    C is TEMPC +1.

exists(Atom, Ch):-
    name(Atom, L),
    name(Ch, [Z]),
    find_element(Z, L, _Count).

注意name(Ch, [Z])提取单个字符。现在

?- exists(pippo,o).
true

值得注意的是

?- find_element(3, [1,2,3,4,1,2,3,4],P).
P = 3 ;
P = 7 ;
false.

?- nth1(P, [1,2,3,4,1,2,3,4], 3).
P = 3 ;
P = 7 ;
false.

你的find_element / 3表现为nth1 / 3,参数1和3交换。

当然,有更简单,更通用的方法来执行此类测试。使用ISO内置 比如sub_atom / 5(一个非常强大的原子检测基元)

?- sub_atom(pippo, _,_,_, o).
true ;

或memberchk / 2,转换为您已经知道的字符列表后(但使用ISO内置atom_codes / 2)

exists(Atom, Ch):-
    atom_codes(Atom, L),
    atom_codes(Ch, [Z]),
    memberchk(Z, L).

要计算sub_atom的出现次数,可以使用库(聚合)

occurences(Atom, Ch, N) :-
  aggregate_all(count, sub_atom(Atom, _,_,_, Ch), N).

?- occurences(pippo, p, X).
X = 3.