LISP查找和替换

时间:2015-11-18 16:36:01

标签: lisp common-lisp

我目前正在解决一些初学者的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)

2 个答案:

答案 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))))))