LISP查找和替换
我目前正在解决一些初学者的Lisp问题。我正在使用公共Lisp 下面我尝试实现一个基本的查找和替换:char1是要在列表中搜索的字符,char2是要替换的字符,而list to search是我正在搜索的列表LISP查找和替换,lisp,common-lisp,Lisp,Common Lisp,我目前正在解决一些初学者的Lisp问题。我正在使用公共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) ((e
(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)
问题:
1
是一个数字z
是一个符号。您的代码与字符无关,字符是CommonLisp中的实际数据类型
如果没有正确的格式和缩进,Lisp编程将变得极其困难
函数append
没有副作用
append
应该避免,因为它很昂贵
由于使用递归,函数可以处理的列表的长度受到堆栈大小的限制。通常情况下,您可能会使用mapcar
。问题:
1
是一个数字z
是一个符号。您的代码与字符无关,字符是CommonLisp中的实际数据类型
如果没有正确的格式和缩进,Lisp编程将变得极其困难
函数append
没有副作用
append
应该避免,因为它很昂贵
由于使用递归,函数可以处理的列表的长度受到堆栈大小的限制。通常在上,您可能会使用
mapcar
。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))))))
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))))))
append
不修改列表,它返回一个新列表。append
不修改列表,它返回一个新列表。谢谢Barmar。修订后的守则似乎是解决这一问题的更明智的办法。我用(cons(要搜索的汽车列表))替换了最后一行,因为这正是我想要的。但是谢谢你。希望我能用这种思维方式来解决一些未来的问题。谢谢Barmar。修订后的守则似乎是解决这一问题的更明智的办法。我用(cons(要搜索的汽车列表))替换了最后一行,因为这正是我想要的。但是谢谢你。希望我能用这种思维方式来解决一些未来的问题。