2012-09-06 65 views
2

在Common Lisp中,我需要以實數列表的形式捕獲用戶輸入。該列表由連續的兩個零終止。例如,5.0 0 6.0 3 2.0 5 1.0 7 13.0 8 0 0應該返回列表(5.0 0 6.0 3 2.0 5 1.0 7 13.0 8)在Lisp中讀取分隔符輸入

我遇到了功能read-delimited-list,它以單個字符爲終點。我可以停止在單個零,但我不知道如何擴展此功能,並且我不知道另一個函數使用分隔字符串而不是字符。

編輯由於接受的答案,我已經開發了以下內容:

(butlast (loop for y = -1 then x for x = (read stream) until (and (= 0 x) (= 0 y)) 
    collect x))) 

似乎更具可讀性我(以及一些在這一點上,我公開admiting我Lisp的眼睛只有3天的時間),我不確定性能的影響(collect在循環退出範圍後追加或反轉列表是否有更簡單的方法來切斷最後一個元素,或者簡單地不附加它?)。

回答

4

對於這樣簡單的情況,您可以在循環中使用read,收集迄今爲止讀取的結果,並在最後兩個爲零時停止。

(defun read-double-zero-terminated-list (stream) 
    (do* ((prev -1 val) 
     (val (read stream) (read stream)) 
     list) 
     ((and (zerop prev) (zerop val)) (reverse (cdr list))) 
    (push val list))) 

read-delimited-list旨在創建專門的語法的情況下,因此它可能是矯枉過正這裏。

+2

不是過度使用,只是明顯錯誤。 'read-delimited-list'在**角色**級輸入中工作......我敢打賭,efritz不想停止在0.17上。 – 6502

+0

@ 6502這是一個有效的點 –

+0

你爲什麼使用do *?在我看來,它也可以與循環一起工作。 – yilmazhuseyin

0

在Common Lisp中解析數字的最佳方法是使用庫parse-number。如果可以逐行讀取用戶輸入,則可以簡單地將行分割爲空格,並對結果使用parse-number