使用Sublime Text处理CLISP。
Exp。在CLISP中:不到1年
我试图解决这个问题已经有一段时间了……可能没有成功……
实际上,我必须创建一个函数,该函数将修改列表并仅保留等于或大于给定数字的子列表(在下面观看)
我必须处理的列表:
(setq liste '((a b) c (d) (e f) (e g x) f))
我应该找到这个结果:
(lenght 2 liste) => ((a b) (e f) (e g x))
liste => ((a b) (e f) (e g x))
这是我的代码:
(defun lenght(number liste)
(cond
((atom liste) nil)
((listp (car liste))
(rplacd liste (lenght number (cdr liste))) )
((<= (lenght number (car liste)) number)
(I don't know what to write) )
((lenght number (cdr liste))) ) )
如果您能给我一些线索以便让我找到好的结果,那将非常好。
谢谢大家。
答案 0 :(得分:3)
修改列表没有多大意义,因为在列表的开头保留原始参考会变得毛茸茸。返回新列表。
这是一个过滤操作。为此,Common Lisp中常用的运算符是remove-if-not
(或remove-if
或remove
,具体取决于条件)。它使用一个谓词,该谓词应返回是否应保留该元素。在这种情况下,它似乎是(lambda (element) (and (listp element) (>= (length element) minlength)))
。
(defun filter-by-min-length (minlength list)
(remove-if-not (lambda (element)
(and (listp element)
(>= (length element) minlength)))
list))
在许多情况下,当在编译时知道条件时,loop
会生成更快的编译代码:
(defun filter-by-min-length (minlength list)
(loop :for element :in list
:when (and (listp element)
(>= (length element) minlength))
:collect element))
这将返回一个满足条件的新列表。您会像(let ((minlength-list (filter-by-min-length 2 raw-list))) …)
这样称呼它。
许多基础课程一开始都坚持以递归方式使用cons单元上的原始操作进行教学。
第一次尝试通常会忽略可能的堆栈耗尽。在每个步骤中,您首先要查看是否在末尾(然后返回nil),是否应该丢弃第一个元素(然后返回其余部分递归的结果)或是否应保留(然后将其保留为递归结果)。
如果可以进行尾部调用优化,则可以将其重构为使用累加器。在每个步骤中,您无需先递归再进行约束,而是将保留的值约束到累加器上,并将其传递给递归。最后,您不返回nil,而是反转累加器并将其返回。
答案 1 :(得分:0)
好吧,在挠挠头直到流血……之后,我已经找到了想要的答案。
很抱歉,这是有效的解决方案(感谢对长度的修正,这有助于我找到解决方案^^):
(defun filter-by-min-length (min-length liste)
(cond
((atom liste) nil)
((and (listp (car liste))(>= (length (car liste)) min-length))
(rplacd liste (filter-by-min-length min-length (cdr liste))) )
((filter-by-min-length min-length (cdr liste))) ) )
答案 2 :(得分:0)
非修改版本
(defun filter-by-min-length (min-length le)
(cond ((atom le) nil)
((and (listp (car le)) (>= (length (car le)) min-length))
(cons (car le) (filter-by-min-length min-length (cdr le))))
(t (filter-by-min-length min-length (cdr le)))))
测试:
(defparameter *liste* '((a b) c (d) (e f) (e g x) f))
(filter-by-min-length 2 *liste*)
;; ((A B) (E F) (E G X))
*liste*
;; ((A B) C (D) (E F) (E G X) F) ; -> *liste* not modified
为了养成良好的习惯,我建议使用defparameter
而不是setq
,因为setq
的行为可能并不总是定义的(请参见here)。在链接中说:
使用
defvar
,defparameter
或let
引入新变量。使用setf
和setq
来突变现有变量。用他们介绍新的 变量是不确定的行为