在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)
。
我遇到了函数read-delimited-list
,它以单个字符作为结束点。我可以停在单零,但我不知道如何扩展此函数,我不知道另一个函数采用分隔字符串而不是char。
编辑由于接受了答案,我开发了以下内容:
(butlast (loop for y = -1 then x for x = (read stream) until (and (= 0 x) (= 0 y))
collect x)))
对我来说似乎更具可读性(此时我公开承认我的Lisp眼睛只有3天),而且我不确定性能影响(collect
追加或{在循环退出范围后反转列表?是否有更简单的方法来删除最后一个元素,或者根本不追加它?)。
答案 0 :(得分: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
适用于创建专门语法的情况,因此在这里可能有些过分。
答案 1 :(得分:0)
在Common Lisp中解析数字的最佳方法是使用库parse-number
。如果您的用户输入可以逐行读取,则可以简单地在空白处拆分行,并在结果上使用parse-number
。