在 common lisp 中编写一个返回列表的否定的函数
我的当前代码出现此错误:
LET: illegal variable specification
(COND (LISTP A (IF (NEGATE A) (NEGATE (REST L)) NIL))
(T (SETF A (-A) (APPEND (LIST A) (REST L)) (NEGATE (REST L)) NIL)))
我当前的代码:
(defun negate(L)
(setq x -1)
(if (not (null L))
(let ((a (fitst L))
(cond (listp a
(if (negate a)
(negate (rest L))
nil))
(t
(setf a (-a) (append (list a)(rest L))
(negate (rest L))
nil))))
)
))
以及它需要通过的测试用例
o List is (1 2 3 4)
o Output should be: (-1 -2 -3 -4)
o List is (1 -2 (3 4))
o Output should be: (-1 2 (-3 -4) )
I get this error with my current code:
LET: illegal variable specification
(COND (LISTP A (IF (NEGATE A) (NEGATE (REST L)) NIL))
(T (SETF A (-A) (APPEND (LIST A) (REST L)) (NEGATE (REST L)) NIL)))
my current code:
(defun negate(L)
(setq x -1)
(if (not (null L))
(let ((a (fitst L))
(cond (listp a
(if (negate a)
(negate (rest L))
nil))
(t
(setf a (-a) (append (list a)(rest L))
(negate (rest L))
nil))))
)
))
and the test cases it needs to pass
o List is (1 2 3 4)
o Output should be: (-1 -2 -3 -4)
o List is (1 -2 (3 4))
o Output should be: (-1 2 (-3 -4) )
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
从最礼貌的意义上来说,你的代码有点不对劲。这周你正在学习 Lisp,不是吗?没关系!这是一门有趣的语言,确实可以做一些很棒的事情。
因此,我将逐步介绍例程的创建过程,并带您参观。
您的基本情况是 -
遍历树更复杂,但让我们来看看这些想法。
本质上,您需要回答三种情况:当前元素是 nil、列表还是原子?
让我们尝试一下这个:
太棒了!
除了...
还有...
哦天哪。我们现在有麻烦了。
首先,我们尝试使用
cons
而不是list
。这解决了奇怪的嵌套列表问题。
很明显,我们陷入了无限递归的循环。这应该是不可能的,因为我们有
not seq
保护。好吧,让我们尝试一下调试。我正在使用 CLISP,我可以通过以下方式跟踪参数:然后,
突然我看到 Crikey 的爆炸
,我忘记了我的 cdr 和 cons up 列表案例!嗯嗯。
让我们试试这个:
对汽车进行递归,对汽车进行回避,将它们放在一起,我们可能会有所发现。
嗯嗯。让我们看一下踪迹。
所以我递归直到-3,然后....它脱落了?奇怪的。啊!我不断地抓取事物的 CDR。 CDR 始终是一个列表。 (cdr '(-3)) 为零!
让我们看看这里......
(翻来覆去)
负数在正数上返回零。噢。
In the most polite sense, your code is a bit off. You're learning Lisp this week, aren't you? That's OK! It's a fun language and can really do some awesome things.
So I'm going to walk through the creation of the routine, and take you along the tour.
Your basic case is -
Walking the tree is more complex, but let's walk through the ideas.
Essentially, you have three cases to answer: is the current element nil, a list or an atom?
Let's try a first cut at this:
That's great!
Except...
And...
Oh boy. We're in trouble now.
First, let's just try a
cons
instead of alist
.That cleans up the weird nested list problem.
It's obvious that we're gotten into a loop of infinite recursion. That shouldn't be possible, because we've got the
not seq
guard. Okay, so let's try an debug. I'm using CLISP, and I can trace arguments with:then,
Suddenly I see an explosion of
Crikey, I forgot my cdr and to cons up the list case! Hmmmm.
Let's try this:
Recurse for the car, recuse on the car, cons them together, we might be on to something.
Hmmmm. Let's take a look at the trace.
So I recurse until the -3, then.... it falls off? Odd. Ah! I'm continually grabbing the CDR of things. A CDR is always a list. (cdr '(-3)) is nil!
Let's see here....
(much rummaging around)
Negate returns nil on positive. D'oh.
我不确定您是否正在寻找一种温和的推动来纠正所提供的代码,或者您是否正在寻求其他方法来做到这一点。我的第一个想法是
mapcar
:然后您可以概括否定方面,并编写
map-tree
来代替,接受一个应用于树中原子的函数:您可以使用一元否定函数来调用它:
这样的调用假设树中的所有叶子都被一元否定函数容纳
nil
。接受 nil 作为树中可能的叶子会使访问算法有点混乱,并且不清楚提供的函数 f 是否应该应用于所有叶子 - 即使是那些都是
nil
——这样函数本身就可以决定是否以及如何处理nil
。此版本的另一个缺陷是它如何处理非 的缺点单元正确的列表。请注意,函数
listp
对所有返回 true cons 单元格——即使那些不构成正确列表的单元格——但mapcar
确实要求其输入是正确列表。我们可以沿着“listp
true”路径,递归调用mapcar
,并让mapcar
因接收到不正确的列表而失败。这意味着上面的算法需要测试 cons 单元格,看看它们是否是正确的列表,然后再将它们交给mapcar
,也许将那些不是叶子的单元格(我不愿意说)此处的“原子”),或者记录预期的树结构由正确列表的正确列表组成。如果您需要接受不一定列出自身的顶级“树”,这意味着一个单独的原子是一个有效的树,或者
nil
是一个有效的树,您可以拆开以下的组成部分上面的函数,并在确定所检查的树是一个列表后编写一个仅使用mapcar
的函数。I'm not sure if you were looking for a gentle nudge to correct the code presented, or if you're soliciting other ways to do it. My first thought went to
mapcar
:You can then generalize out the negation aspect, and write
map-tree
instead, accepting a function to apply to the atoms in the tree:You can call on it with, say, the unary negation function:
Such a call assumes that all the leaves in the tree are either
nil
accommodated by the unary negation function.Accepting
nil
as a possible leaf in the tree makes the visitation algorithm a little messy, and it's not clear whether the provided functionf
should be applied to all leaves—even those that arenil
—so that the function itself can decide whether and how to treatnil
.Another deficiency with this version is how it treats cons cells that are not proper lists. Note that function
listp
returns true for all cons cells—even those that do not constitute proper lists—butmapcar
does require that its input be a proper list. We can wind up along our "listp
true" path, recursively calling onmapcar
, and havemapcar
fail for receiving an improper list. That means that the algorithm above either would need to test cons cells to see if they're proper lists before handing them tomapcar
, perhaps treating those that aren't as leaves (I'm reluctant to say "atoms" here), or be documented that the expected tree structure is made up of proper lists of proper lists.If you need to accept top-level "trees" that are not necessarily lists themselves, meaning that a lone atom is a valid tree, or
nil
is a valid tree, you can tear apart the constituent parts of the function above and write one that only usesmapcar
after determining that the tree under inspection is a list.如果你写:
那么你就将你的代码限制为实数。
如果您使用 Common Lisp 提供的原始 negate 函数,它将适用于任何数字:
If you write:
then you're limiting your code to real numbers.
If instead you use the primitive negate function provided by Common Lisp, it will work on any number:
这就是我要做的。当然,我只考虑数字列表。因此,如果列表不全是数字,它会抛出错误。
Here's what I would do. Of course, I am considering only numberic lists. So, it would throw errors if the list isn't all numeric.
您可以通过以下过程来实现这一点:
也可以有另一个版本。我尝试编写一个尾递归程序,但它不完全是tr。
实现了同样的事情,只是它没有给出与原始顺序相同的顺序。我现在无法解决这个问题:
You can achieve this by the following procedure:
one can also have another version. i have tried to write a tail-recursive procedure, but it is not fully tr.
achieves same thing except it does not give the same order as original one. i can not now fix this: