String 序言列表到逗号分隔字符串

String 序言列表到逗号分隔字符串,string,list,prolog,String,List,Prolog,我有一个类似于[apple,orange]的列表,我想在Prolog中将其转换为类似于“apple,orange”的字符串。您有什么想法吗?在SWI Prolog中,您可以将与输出一起使用到/2。下面是两个版本,一个使用write/1,另一个使用writeq/1。你的问题不清楚你需要什么样的行为 ?- List = [apple, 'ora\\nge'], with_output_to(codes(Codes), write(List)), format("~s", [Codes]). [

我有一个类似于
[apple,orange]
的列表,我想在Prolog中将其转换为类似于
“apple,orange”
的字符串。您有什么想法吗?

在SWI Prolog中,您可以将
与输出一起使用到/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|...].

我是一个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'] .

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

1) 使用字符串\u to \u 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).

您可能需要进行一些尾部递归优化

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

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

只有当列表至少有两个元素时,这才会统一,并且会阻止得到两个解决方案。

在SWI Prolog中,您可以简单地使用
原子列表\u concat/3
原子字符串/2

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

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

term_string(30 char min S.O.)

@selda:SWI-Prolog手册中查找
和_-output_-to
帮助(和_-output_-to)。实验(因为文档对我几乎没有用处)我发现,如果你只运行前两个子句,
List=[apple,'orange'],和_-output_-to(code(code),writeq(List))
,它将
code
定义为与
list
相对应的数字列表。第一个字符91必须是括号字符;尾随的
|
表示还有更多未关闭的
format()
然后以某种模糊的语言将其打印到屏幕上,
~s
表示。。。呃…我还有一个问题,我想从这个列表中找到一个谓词。我有一张单子[苹果,橘子]。我试着做水果(苹果、橘子)。你能帮我吗?@selda如果你有一个新问题,那么就把它作为一个新问题发布,而不是作为对无关答案的评论。这个问题已经得到了回答:请解释一下你为什么要这么做?你想把清单打印出来吗?是否要将其序列化为文件?输入列表的本质是什么:它能包含其他列表或复杂术语吗?它能包含变量和变量共享吗?这适用于原子列表,而且很方便——但如果其中一个元素是复杂的(如[apple,ba(nana)]嗨,@ USE10221289.你能为你的答案提供更多的解释吗?除了解释之外,还请考虑添加一个示例代码来演示你的解决方案的效果。