我意识到这是一个非常基本的问题,但我刚刚开始使用CL,我想知道如何从标准输入中获取输入,如:
1 2 3 4 5
并将其存储在数组中。
我试过了:
(setq array (read-line))
然后检查类型给出了缺点。
我也尝试过像这样构建一个数组:
(setf array (make-array n :element-type 'number))
其中n是我输入的值的数量,但在此之后我就丢失了。我是否需要使用循环或有没有办法在没有循环的情况下执行此操作?
感谢。
答案 0 :(得分:3)
您需要执行以下步骤:
看起来像这样:
(defun read-array (stream)
(let* ((line (read-line stream))
(items (split-sequence #\Space line))
(numbers (map 'vector #'parse-integer items)))
numbers))
(Split-sequence
来自同名的图书馆。)
这只是基本的实现,您可能希望清理输入,并在任何空格上进行拆分。
我建议不要以任何方式使用read
来阅读用户输入,因为读者可以做更多事情而且你需要非常小心用户输入。
答案 1 :(得分:1)
预定义函数read-line
返回一个字符串(请参阅manual)。
从该字符串中获取数组(假设数字在一行上)的一种简单方法是通过添加必要的语法来操作返回的字符串,以便通过函数{{1将其作为文字数组读取}}。这是一个简单的功能,改编自Paul Graham撰写的优秀On Lisp书中的列表:
read-from-string
当然,如果数字在多行上,则需要进行某种迭代。
答案 2 :(得分:1)
可以通过使用流来读取字符串。然后,只要有数字,就会调用read
,将其收集到列表中并将列表转换为矢量。
CL-USER 36 > (coerce (with-input-from-string (stream "1 2 3 4 5")
(loop for n = (read stream nil nil)
while (numberp n)
collect n))
'vector)
#(1 2 3 4 5)
或:one创建一个可以增长的向量 - 在Common Lisp中,向量应该是可调整的(当大小未知时)并且有一个填充指针。然后从字符串流中读取并将数字推送到矢量上。
CL-USER 40 > (let ((vector (make-array 0 :adjustable t :fill-pointer t)))
(with-input-from-string (stream "1 2 3 4 5")
(loop for n = (read stream nil nil)
while (numberp n)
do (vector-push-extend n vector)))
vector)
#(1 2 3 4 5)
答案 3 :(得分:1)
您正在描述的Common Lisp中的文字数组的语法是#(1 2 3 4 5)
。您只需键入{而不是1 2 3 4 5
,然后读取:
CL-USER> (read)
; type "#(1 2 3 4 5)" (no quotes)
#(1 2 3 4 5) ; return value
CL-USER> (let ((array (read)))
(type-of array))
; type "#(1 2 3)" (no quotes)
(SIMPLE-VECTOR 3)