Prolog list to comma separated string

£可爱£侵袭症+ 提交于 2020-02-23 15:59:10

问题


I have a list like [apple, orange]and I want to convert it to a string like "apple,orange" in Prolog. Do you have any idea?


回答1:


In SWI-Prolog you can simply use atomic_list_concat/3 and atom_string/2:

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

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



回答2:


In SWI-Prolog you can use with_output_to/2. Below are two versions, one using write/1 and the other writeq/1. It's not clear from your question what kind of behaviour your require.

?- 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|...].



回答3:


if you use swi-prolog you can also do the following:

1) use the string_to_list/2 (you can give a list and get a string or give a string and get a list). the problem is that it wont insert commas so you will have to insert commas between the elements of your list manually; something like

insert_commas([],[]).
insert_commas([H|T],[H,', '|TC]):-
   insert_commas(T,TC).

so your predicate would be something like:

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

2)you can use swritef/3 and string_concat/3. swritef/3 works like writef/2 but instead of writing in the output it creates a string with the data.

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).

you might want to do some tail recursion optimisations




回答4:


I am a Prolog novice - but this is what I came up with.

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).

which gives:

?- 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' .

and:

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

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

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



回答5:


Sorry, don't have enough rep to add this comment to Gavin Lock's answer. Gavin's solution is good so far as it goes, but it should be tweaked to avoid giving duplicate answers (or, rather, a variation on the same answer). The problem is that a list with a single atom will unify to two clauses in list_codes/2: the second AND the third clause. (A list with a single element still has a tail, i.e. the empty list.) I believe only the second clause binding is desired. The third clause seems to be designed to be recursive for lists that still have at least two elements. Therefore I recommend changing this clause to be:

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

This will only unify when the list has at least two elements, and will prevent getting two solutions.




回答6:


term_string (30 char min S.O.)



来源:https://stackoverflow.com/questions/5879956/prolog-list-to-comma-separated-string

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!