Follow up to this question。如何在不使用列表或内置谓词atom_chars/2.
split_word(Word, Letter, Rest).
如果Letter是该单词的第一个字母。
我在分割字符串方面遇到困难,而且我不知道如何利用''
作为" splitter"。为了获得灵感,我尝试使用atom_chars/2
检查predicate_property(atom_char(_,_), P).
的源代码,但是在文件中我没有找到任何有用的信息。
帮助表示赞赏。
答案 0 :(得分:1)
据我所知,您不想使用atom_chars/2
,但可以使用其他内置谓词。您可以使用sub_string/5
和string_length/2
以这种方式在SWI Prolog中解决问题:
split(_,0).
split(S,Len):-
Len > 0,
Len1 is Len-1,
sub_string(S,0,1,_,Sub), %get the first letter
writeln(Sub),
sub_string(S,1,Len1,_,Sub1), %get the rest of the string
split(Sub1,Len1).
solve(S):-
string_length(S,Len),
split(S,Len).
?- solve("abcd").
a
b
c
b
true
答案 1 :(得分:1)
通过“将字符串拆分为原子”,我假设您的意思是“将字符串拆分为字符列表”。
首先,我们需要区分字符串与*原子。在Prolog中,用双引号表示的字符串通常是字符代码列表,而用单引号表示的 atom 或以小写字母开头的名称,是一个象征。见What is the difference between ' and " in Prolog。这是GNU Prolog中的样子:
| ?- X = "abc". % A string of characters
X = [97,98,99]
yes
| ?- X = 'abc'. % An atom
X = abc
yes
| ?- X = abc. % An atom
X = abc
yes
| ?- X = 'Abc'. % An atom
X = 'Abc'
yes
| ?-
所以,如果你想从字符串中获取字符代码列表的头部和其余部分,就像统一它们一样简单:
| ?- "abcd" = [H | T].
H = 97
T = [98,99,100]
yes
| ?-
另一方面,如果你想用 atom 做这件事,那么首先需要使用atom_chars/2
将原子转换为字符代码:
| ?- atom_chars(abc, [H|T]).
H = a
T = [b,c]
yes
| ?-
在SWI Prolog中,他们允许使用双引号来表示整数字符串,而不表示字符代码列表。但它与原子不同。见Why has the representation of double quoted text changed?。以下是SWI Prolog中的一些查询:
1 ?- "abc" = 'abc'.
false.
2 ?- X = "abc".
X = "abc".
3 ?- "abc" = [H|T].
false.
4 ?- atom_chars("abc", [H|T]).
H = a,
T = [b, c].
5 ?- atom_chars(abc, [H|T]).
H = a,
T = [b, c].
奇怪的是,"abc"
与原子abc
不同(如失败的统一所示),但atom_chars/2
对待"abc"
与原子相同,abc
。
Prolog有标志影响其行为。特别是在SWI Prolog中,有double_quotes
标志,其值可以修改,以便双引号表示在传统的Prolog意义上表现,如上面的GNU Prolog示例所示。
回到手头的问题,原子处理谓词对于Prolog来说是相当基础的,所以如果你需要在闭卷考试中进行原子处理,那么最好先了解基本原理。