2011-05-04 56 views
4

我有一個像[apple, orange]這樣的列表,我想在Prolog中將它轉換爲像"apple,orange"這樣的字符串。你有什麼主意嗎?序言列表到字符串

+1

請解釋一下你爲什麼要這麼做?你想漂亮的打印清單嗎?你想把它序列化成一個文件嗎?輸入列表的性質是什麼:它是否可以包含其他列表或複雜的術語,它是否可以包含變量和變量共享? – Kaarel 2011-05-04 11:11:22

回答

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|...]. 
+0

你能解釋一下嗎? – selda 2011-05-04 08:24:42

+0

@selda:在SWI-Prolog手冊中查找'with_output_to':'help(with_output_to)。' – 2011-05-04 08:50:55

+0

實驗(因爲文檔對我來說幾乎沒用)我發現如果你只運行前兩個子句,List = [apple,'orange'],with_output_to(codes(Codes),writeq(List))'它將'Codes'定義爲對應於List的數字列表。第一個91必須是括號字符;尾部的'|'表示還有更多的未顯示。 'format()'然後將它打印到屏幕上,用一些晦澀的語言,其中'〜s'表示...呃... – 2018-02-02 21:31:28

0

我是一名序言新手 - 但這是我想出的。

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'] . 
+0

謝謝你的回答 – selda 2011-05-04 10:35:11

+0

我也有一個問題,我想從這個謂詞名單。我有一個清單[蘋果,橙]。我嘗試製作水果(蘋果,橙子)。你可以幫我嗎? – selda 2011-05-04 10:37:15

+0

@selda如果您有新問題,請將其作爲新問題發佈,而不是作爲對無關答案的評論。這個問題雖然已經得到了回答:http://stackoverflow.com/questions/612604/converting-a-list-into-a-term-in-prolog – Kaarel 2011-05-04 11:06:52

1

如果使用SWI-序言你也可以做到以下幾點:

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

你可能想要做一些尾遞歸的優化

0

對不起,沒有足夠的代表加入到加文鎖的回答此評論。加文的解決方案在目前爲止還不錯,但應該調整以避免給出重複的答案(或者相同的答案)。問題是具有單個原子的列表將統一到list_codes/2中的兩個子句:第二個AND第三個子句。 (具有單個元素的列表仍然有一個尾部,即空列表。)我相信只有第二個子句綁定是所需的。第三條似乎被設計爲對仍然至少有兩個元素的列表進行遞歸。因此,我建議改變這個條款是:

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

當列表至少有兩個元素這隻會統一,並防止獲得兩個解決方案。

4

在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". 
+0

這適用於原子列表,它很方便 - 但如果一個的元素是複雜的(如[apple,ba(nana)],它錯了。 – 2018-02-02 21:18:16