我使用SBCL和quicklisp的iterate
软件包解决了Euler项目的第八个问题。在我的代码中,我定义了一个函数,可以将数字转换为数字列表。这是源代码:
(defun number-to-list (n)
(iter (for c in-string (write-to-string n)) (collect (digit-char-p c))))
在collect
这两个条款iter
,并loop
做一个清单出来的值。是否可以代替生成矢量(一维数组)?
我唯一的选择是将生成的列表转换number-to-list
为向量吗?因为这似乎效率低下(尽管可能不是那么低效)
通常存在一个大问题:结果向量将有多大?最好事先知道,然后我们可以用正确的大小分配一次向量。否则,我们将找到解决该问题的方法:使用可调整大小的向量,先分配一个列表,然后再复制到结果向量中,再使用填充指针分配更大的向量,...
如果有序列,则可以使用Common Lisp函数MAP
:如果源对象是向量(此处为字符串),则获取长度很便宜。
CL-USER 1 > (map 'vector
#'digit-char-p
(write-to-string 5837457324534))
#(5 8 3 7 4 5 7 3 2 4 5 3 4)
您可以使用ITERATE
和收集向量:
FOO 32 > (defun number-to-vector (n)
(iter (for c in-string (write-to-string n))
(collect (digit-char-p c) result-type vector)))
NUMBER-TO-VECTOR
FOO 33 > (number-to-vector 8573475934)
#(8 5 7 3 4 7 5 9 3 4)
如果看宏扩展,它实际上会收集到一个列表中,然后调用COERCE
以创建向量。因此:没有效率的胜利。
请注意,这是另一个ITERATE
比其中更强大的示例LOOP
:标准LOOP
不能直接从collect返回向量。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句