检查List中的任何元素是否以特定字符开头

时间:2013-09-19 12:05:18

标签: prolog

我有一个单词列表,例如[cola,fanta,pepsi],我想写一个谓词,检查是否有任何元素以指定的字符开头。

到目前为止我的代码如下:

chk_first_letter(Char,[]):-fail.
chk_first_letter(Char, [H|T]):-
    perform_check(Char, H);
    chk_first_letter(Char, T).
perform_check(Char,[First|_]):-memberchk(Char, First).

然而,咨询我的文件并调用chk_first_letter(p,[cola,fanta,pepsi])即使pepsi以p开头也不会给我。

我尝试使用Char == First而不是memberchk(Char,First),但它也没有用。我不确定区别。

3 个答案:

答案 0 :(得分:4)

你有一个原子列表,你的perform_check/2比较了两个原子。原子一个字符列表!您需要使用原子处理,例如:

perform_check(First, Word) :-
    sub_atom(Word, 0, 1, _After, First).

http://gprolog.univ-paris1.fr/manual/html_node/gprolog043.html#sec200

本节中有许多其他内置函数可供使用,例如将原子分解为字符或字符代码(atom_chars/2atom_codes/2)。但是sub_atom/5也可以让你轻松做到:

任何长度的前缀:

sub_atom(Word, 0, _Length, _After, Prefix).

后缀:

sub_atom(Word, _Before, _Length, 0, Suffix).

答案 1 :(得分:3)

首次尝试:

chk_first_letter(Char, Atoms) :- member(A, Atoms), atom_chars(A, [Char|_]).

atom_chars / 2这是一个ISO谓词。

你的代码几乎可以正常工作,可以这样简化:

chk_first_letter(Char, [H|T]):-
    atom_chars(H, [Char|_]);
    chk_first_letter(Char, T).

答案 2 :(得分:2)

期望以列表作为第二个参数调用

memberchk。在您的情况下,您将为其提供单个字符。

然后你可以通过利用统一来完全取消它:

perform_check(Char,[Char|_]).

这假定您的字符串类型是字符列表(无论字符格式如何)。如果你打算直接对原子进行操作,你可以这样做:

perform_check(Char,String) :- atom_concat(Char,_,String)

还有一些步骤可以使您的代码更加惯用,但这似乎是错误的部分。