递归检查列表中的原子
我正在尝试编写一个小型递归程序来测试列表并在每个元素都是原子时返回t。我遇到的问题是,当函数收到空列表时,它返回 t 而不是所需的 nil 结果。我无法想出一种方法让它返回 nil 对于最初的空列表,并且仍然以递归方式正常运行。
(defun only-atoms (in)
(if (null in)
t
(and (atom (first in)) (only-atoms (cdr in)) )
)
)
I am attempting to write a small recursive program that tests a list and returns t if every element is an atom. The problem I am having is that when the function receives an empty list, it returns t instead of the desired result of nil. I cannot come up with a way to have it return nil for an initially empty list and still function properly in a recursive manner.
(defun only-atoms (in)
(if (null in)
t
(and (atom (first in)) (only-atoms (cdr in)) )
)
)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
该函数可以在没有递归的情况下使用例如
every
来实现,如下所示:当涉及到您所陈述的问题时,函数返回
T
而不是所需的NIL 结果
当使用空列表调用函数时:如果
(null in)
为 true,则递归实现显式返回T
,这解释了您的发现。只需将其更改为所需的值NIL
。考虑将if
结构更改为and
。仅当列表有多个项目时才进行递归调用。对
(rest in)
进行适当的测试就可以了。如果列表位于最后一项,则提供真值而不是进行递归调用。仔细找到
only-atoms
调用以确保该函数可以尾递归。例如:
The function can be implemented without recursion using e.g.
every
, as in:When it comes to your stated problem that the function returns
T
instead of the desired result ofNIL
when the function is called with an empty list:Your recursive implementation explicitly returns
T
if(null in)
is true, which explains your finding. Simply change it to the desired valueNIL
. Consider changing theif
construct toand
.Only make the recursive call when the list has more than one item. A well placed test for
(rest in)
will do. Provide a true value instead of making the recursive call if the list is at its last item.Carefully locate the
only-atoms
call to ensure that the function can be tail-recursive.For example:
使用 COND,它允许您测试几种情况:
Use COND, which allows you to test for several cases:
空列表确实满足每个元素都是原子的条件!您要求它至少包含一个元素是一项附加要求。
表达“列表中的每个元素都是一个原子”的最简单方法是
(every #'atom list)
。您可以使用和
将其与您的附加要求结合起来。如果您坚持以 SICP 风格递归执行此操作,请将您的需求分开:
The empty list does fulfill the condition that every element is an atom! Your requirement that it should contain at least one element is an additional requirement.
The simplest way to express "every element of the list is an atom" is
(every #'atom list)
. You can combine it with your additional requirement withand
.If you insist on doing it recursively in SICP-style, separate your requirements:
这个解决方案工作正常:
然而,一个更优雅的解决方案(没有递归)将是:
This solution works correctly:
However a much more elegant solution(with no recursion) would be:
您可以将函数分成两部分,并在进入递归之前提供初始
nil
筛选。以下代码是这样做的一种方法(我试图使其尽可能接近提供的代码):这也是使函数尾部递归的好机会:
You can split your function in two, and provide the initial
nil
screening before you enter recursion. The following code is one way to do so (I tried to keep it as close to provided code as possible):This is also a good opportunity to make your function tail recursive: