Prolog列表以逗号分隔的字符串

时间:2011-05-04 07:25:20

标签: string list prolog

我有一个像[apple, orange]这样的列表,我希望将它转换为Prolog中的"apple,orange"之类的字符串。你有什么想法吗?

6 个答案:

答案 0 :(得分:6)

在SWI-Prolog中,您只需使用atomic_list_concat/3atom_string/2

即可
?- atomic_list_concat([apple, banana, oranges], ',', Atom), atom_string(Atom, String).

Atom = 'apple,banana,oranges',
String = "apple,banana,oranges".

答案 1 :(得分:4)

在SWI-Prolog中,您可以使用with_output_to/2。以下是两个版本,一个使用write/1,另一个使用writeq/1。从你的问题不清楚你需要什么样的行为。

?- List = [apple, 'ora\\nge'], with_output_to(codes(Codes), write(List)),
   format("~s", [Codes]).
[apple,ora\nge]
List = [apple, 'ora\\nge'],
Codes = [91, 97, 112, 112, 108, 101, 44, 111, 114|...].

?- List = [apple, 'ora\\nge'], with_output_to(codes(Codes), writeq(List)),
   format("~s", [Codes]).
[apple,'ora\\nge']
List = [apple, 'ora\\nge'],
Codes = [91, 97, 112, 112, 108, 101, 44, 39, 111|...].

答案 2 :(得分:1)

如果您使用swi-prolog,您还可以执行以下操作:

1)使用string_to_list / 2(您可以给出一个列表并获取一个字符串或给一个字符串并获取一个列表)。问题是它不会插入逗号,所以你必须手动插入列表元素之间的逗号;

之类的东西
insert_commas([],[]).
insert_commas([H|T],[H,', '|TC]):-
   insert_commas(T,TC).

所以你的谓词应该是这样的:

list_string_with_commas(L,S):-
   insert_commas(L,LC),
   string_to_list(S,LC).

2)你可以使用swritef / 3和string_concat / 3。 swritef / 3的工作方式与writef / 2类似,但不是在输出中写入,而是创建带有数据的字符串。

list_string_with_commas([],"").
list_string_with_commas([H,T],S):-
    swritef(SH,"%t, ",[H]),
    list_string_with_commas(T,ST),
    string_concat(SH,ST,T).

你可能想做一些尾递归优化

答案 3 :(得分:0)

我是Prolog的新手 - 但这就是我想出来的。

list_codes([], "").

list_codes([Atom], Codes) :- atom_codes(Atom, Codes).

list_codes([Atom|ListTail], Codes) :-
        atom_codes(Atom, AtomCodes),
    append(AtomCodes, ",", AtomCodesWithComma),
    append(AtomCodesWithComma, ListTailCodes, Codes),
    list_codes(ListTail, ListTailCodes).

list_string(List, String) :-
    ground(List),
    list_codes(List, Codes),
    atom_codes(String, Codes).

list_string(List, String) :-
    ground(String),
    atom_codes(String, Codes),
    list_codes(List, Codes).

给出:

?- list_string([], S).
S = '' .

?- list_string([apple], S).
S = apple .

?- list_string([apple, orange], S).
S = 'apple,orange' .

?- list_string([apple, orange, peach], S).
S = 'apple,orange,peach' .

和:

?- list_string(L, '').
L = [] .

?- list_string(L, 'banana').
L = [banana] .

?- list_string(L, 'banana,litchi').
L = ['banana,litchi'] .

答案 4 :(得分:0)

抱歉,没有足够的代表将此评论添加到Gavin Lock的答案中。到目前为止,Gavin的解决方案很好,但应该进行调整以避免给出重复的答案(或者更确切地说,是对同一答案的变化)。问题是具有单个原子的列表将统一到list_codes / 2中的两个子句:第二个和第三个子句。 (具有单个元素的列表仍然具有尾部,即空列表。)我认为只需要第二个子句绑定。第三个子句似乎被设计为对仍然至少包含两个元素的列表进行递归。因此,我建议将此条款更改为:

list_codes([Atom,Next|ListTail], Codes) :-
    atom_codes(Atom, AtomCodes),
    list_codes([Next|ListTail], ListTailCodes),
    append(AtomCodes, ",", AtomCodesWithComma),
    append(AtomCodesWithComma, ListTailCodes, Codes).

这只会在列表至少包含两个元素时统一,并且会阻止获得两个解决方案。

答案 5 :(得分:-1)

term_string(S.O。最少30个字符)