(defun foo (in i out)
(if (>= i 0)
(progn
(append (list (intern (string (elt in i)))) out)
(print output)
(foo in (- i 1) out )
)
(out)
)
)
(print (foo "abcd" (- (length "abcd") 1) (list)))
我试图将此字符串返回为(a b c d)。但是它确实返回nil作为输出。我在这里做什么错?谢谢
答案 0 :(得分:2)
我不知道这与追加有什么关系。我认为您想要的输出也很奇怪,因此您不应该执行自己的操作。字符的正确对象是字符而不是符号。不过,获取列表(a b c d)
的一种好方法如下:
CL-USER> '(a b c d)
在运行时插入符号很奇怪,所以也许您会这样:
(defconstant +alphabet+ #(a b c d e f g h i j k l m n o p q r s t u v w x y z))
(defun foo (seq)
(map 'list
(lambda (char)
(let ((index (- (char-code char) (char-code #\a))))
(if (< -1 index (length +alphabet+))
(svref +alphabet+ index)
(error "not in alphabet: ~c" char))))
seq))
答案 1 :(得分:1)
您只有一些小错误。首先,我们需要摆脱output
和(output)
;这些与代码无关。看来您正在使用名为output
的变量,然后将其重命名为out
,而没有修复所有代码。此外,(output)
是一个函数调用;它希望存在一个名为output
的函数。
第二,必须以某种方式捕获append
的结果;在progn
中,您只是将其丢弃。这是一个工作版本:
(defun foo (in i out)
(if (>= i 0)
(foo in (1- i) (cons (intern (string (elt in i))) out))
out))
还请注意,我使用的是效率更高且惯用的(append (list X) Y)
,而不是您的(cons X Y)
。此cons
操作的结果必须传递到foo
。 out
参数是我们的累加器,它通过尾部递归进行处理;它保存了我们到目前为止有多少个列表。
即我们不能拥有(progn <make-new-list> (foo ... <old-list>))
;只会创建新列表并将其丢弃,然后将旧列表传递给递归调用。由于旧列表最初以nil
的形式出现,因此我们一直沿用此nil
,并且当索引达到零时,就会弹出该列表。我们需要(foo .... <make-new-list>)
,这就是我所做的。
测试:
[1]> (foo "" -1 nil)
NIL
[2]> (foo "a" 0 nil)
(|a|)
[3]> (foo "ab" 1 nil)
(|a| |b|)
[4]> (foo "abcd" 3 nil)
(|a| |b| |c| |d|)
[5]> (foo "abcd" 3 '(x y z))
(|a| |b| |c| |d| X Y Z)
最后,如果您希望(|a| |b| |c| |d|)
符号显示为(a b c d)
,则必须摆弄readtable-case
。
当然:
[6]> (foo "ABCD" 3 nil)
(A B C D)