【问题标题】:Issue using cons function in Lisp?在 Lisp 中使用 cons 函数有问题吗?
【发布时间】:2014-02-19 14:44:42
【问题描述】:

我正在学习 Lisp,我必须编写一个函数,它的返回值是一个列表,其中包含来自给定输入的奇数(如果有的话)。在代码中我有这个:

(defun f3 (a)
   (cond
    ((null a) nil )
    ((and (numberp (car a)) (oddp (car a))) (cons (car a) (f3 (cdr a))))
    (T (f3 (cdr a)))
   ) ; end cond
)

我本来想用append函数,但是一直报错。

建议我使用 cons 函数。当我这样做时,我的功能开始工作(代码在上面)。我原来有这个:

(defun f3 (a)
    (cond
       ((null a) ())
       ((and (numberp (car a)) (oddp (car a))) (append (f3 (cdr a)) (car a))))
       (T (append () (f3 (cdr a))))
    )
)

但不断出错。例如,如果我打电话给(f3 '(1 2 3)),它会说“错误 3 不是 LIST 类型”。所以,我的问题是为什么 cons 在这里起作用,为什么 append 不起作用?缺点是如何工作的?提前致谢。

【问题讨论】:

    标签: lisp append


    【解决方案1】:

    append 想要列表参数,而(car a) 不是列表。而不是(car a),你需要(list (car a))。换句话说,(append (f3 (cdr a)) (list (car a)))

    这基本上可以工作,但你会以相反的顺序得到结果。所以应该是(append (list (car a)) (f3 (cdr a)))

    另请注意,您的 (append () (f3 (cdr a))) 仅相当于 (f3 (cdr a))

    您原来的结果将是:

    (defun f3 (a)
        (cond
           ((null a) ())
           ((and (numberp (car a)) (oddp (car a))) 
              (append (list (car a)) (f3 (cdr a)))))
           (T (f3 (cdr a)))))
    

    但是,您通常不会使用 append 将单个元素添加到列表中。使用cons 会更自然地完成。所以

      (append (list (car a)) (f3 (cdr a)))
    

    更合适的做法是:

      (cons (car a) (f3 (cdr a)))
    

    这最终将您带到您展示的工作版本。

    【讨论】:

    • 正是我想要的。这是一个写得很好的答案。
    【解决方案2】:

    虽然mbratch's answer 之类的内容可以帮助您了解列表操作(因此可能是对您更有用的答案在您的研究中),但了解列表操作也很重要您正在使用的语言的标准库。在这种情况下,您试图过滤掉除奇数之外的所有内容。使用remove-if-not,就是:

    (defun keep-odd-numbers (list)
      (remove-if-not (lambda (x)
                       (and (numberp x) (oddp x)))
                     list))
    
    CL-USER> (keep-odd-numbers '(1 a 2 b 3 c 4 d 5 e))
    ;=> (1 3 5)
    

    【讨论】:

    • 这很有帮助。谢谢!
    • 说得好乔希(+1)。实际上,我在掩饰最优解决方案,以支持解释所提出的解决方案。
    【解决方案3】:

    虽然这不能解决@mbratch 提供的实际问题,但这是我使用 LOOP 宏(标准库的另一部分)实现类似这样的方法:

    (defun keep-odd-numbers (list)
      (loop for x in list collecting x when (and (numberp x) (oddp x))))
    

    【讨论】:

    • when (and (numberp x) (oddp x)) collect xloop 非常灵活:))。
    猜你喜欢
    • 2021-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-24
    相关资源
    最近更新 更多