【问题标题】:Trimming a list using Lisp programming language使用 Lisp 编程语言修剪列表
【发布时间】:2019-09-24 00:15:37
【问题描述】:

我对 Lisp 语言有点陌生,我正在尝试编写一个函数来修剪并返回列表的一部分。我输入的代码如下:

(defun trim-to (symbol list)
   (cond
   ((null list) 0) 
   ((equal symbol (car list)) (cons symbol (cdr list))
   (t (trim-to (cdr list))))))

运行函数的代码是:

(trim-to 'c '(a b c d e))

它应该输出(c d e),但它只返回NIL。知道我的代码做错了什么吗?

【问题讨论】:

  • 您的意思是'(),而不是基本情况下的0?当找到symbol 时,为什么将列表前面的cons 回到该列表的cdr 上?对trim-to 的最后一次呼叫是否遗漏了什么?
  • 我这样做是希望它只会在列表的后面和符号上的字符,但我想我知道这是什么问题。最后一行是如果在列表的第一个位置找不到字符(如迭代器),则继续前进
  • 检查递归调用的参数:需要多少个参数,你有多少个?
  • 缩进你的代码。它没有正确缩进。然后检查代码,看看它是否有意义。你的 Lisp 也可能有 TRACE 和 STEP...

标签: list lisp common-lisp


【解决方案1】:

它应该输出 (c d e) 但它只返回 NIL。知道我的代码做错了什么吗?

这是您的代码,已重新整理:

(defun trim-to (symbol list)
  (cond
    ((null list) 0)
    ((equal symbol (car list))
     (cons symbol (cdr list))
     (t (trim-to (cdr list))))))

当我用 SBCL 编译它时,我有以下警告:

警告: 函数 T 是未定义的,其名称由 ANSI CL 保留,因此即使 如果稍后定义,这样做的代码将不可移植。

确实,您的代码在正常评估上下文中具有以下形式(t ...);您打算将它作为 cond 表单中的一个子句,但之前缺少一个右括号,这使得 (t ...) 表单成为在 (cons symbol (cdr list)) 之后评估的表达式(这样做,它使之前的表单无用,因为它的结果被丢弃)。突出显示匹配括号的编辑器可以帮助您(大多数现代编辑器都是开箱即用的)。

由于您的测试与cond 的第二个子句不匹配,因此代码没有到达您要调用名为T 的函数的部分,并且您在运行时没有出错。但是cond 表单的默认值为 NIL,这就是您看到该结果的原因。

在没有给出完整答案的情况下,以下是您的示例的预期执行轨迹:

0: (TRIM-TO C (A B C D E))
  1: (TRIM-TO C (B C D E))
    2: (TRIM-TO C (C D E))
    2: TRIM-TO returned (C D E)
  1: TRIM-TO returned (C D E)
0: TRIM-TO returned (C D E)

【讨论】:

  • 谢谢!我会尝试这些并追溯我的代码以找到我出错的地方
猜你喜欢
  • 2022-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-18
  • 2010-09-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多