我目前正在解决一些初学者的Lisp问题。我正在使用Common Lisp。
下面我尝试实现基本查找和替换:char1是要在列表中搜索的字符,char2是要替换它的字符,list-to-search是我正在搜索的列表。
(defun find-and-replace (char1 char2 list-to-search &optional (ammended-list(list)))
(cond
((null list-to-search) ammended-list)
((eql char1 (car list-to-search))
(append ammended-list (list char2))
(find-and-replace char1 char2 (cdr list-to-search)))
(t (append ammended-list
(list (car list-to-search))
(find-and-replace char1 char2 (cdr list-to-search))))))
当我跑步时:
(find-and-replace '1 'z '(1 2 3 1 4 5)) => (2 3 4 5)
我期望的地方:
(z 2 3 z 4 5)
答案 0 :(得分:4)
的问题:
1
是一个数字。 z
是一个符号。您的代码与字符无关,它们是Common Lisp中的实际数据类型。
如果没有正确的格式和缩进,Lisp编程变得非常困难。
函数append
没有副作用。
append
应该避免,因为它昂贵。
您的函数可以使用的列表,由于使用递归而受到堆栈大小的限制。通常情况下,可能会使用mapcar
代替。
答案 1 :(得分:2)
append
不修改参数列表,您需要将结果分配回变量。当你进行递归调用时,你没有传递修改后的列表,所以它总是使用初始值nil
。
(defun find-and-replace (char1 char2 list-to-search &optional (ammended-list(list)))
(cond
((null list-to-search) ammended-list)
((eql char1 (car list-to-search))
(setq ammended-list (append ammended-list (list char2))
(find-and-replace char1 char2 (cdr list-to-search) ammended-list))
(t (setq ammended-list (append ammended-list (list char1))
(find-and-replace char1 char2 (cdr list-to-search) ammended-list))))
但这不是编写函数的最佳方法。 APPEND
是一项昂贵的操作,每次都必须复制列表。更好的是一次构建一个新元素:
(defun find-and-replace(char1 char2 list-to-search)
(cond ((null list-to-search) nil)
((eql char1 (car list-to-search))
(cons char2 (find-and-replace char1 char2 (cdr list-to-search))))
(t (cons (car list-to-search) (find-and-replace char1 char2 (cdr list-to-search))))))