使用Common与Common Lisp进行意外列表复制

Joh*_*ver 2 lisp common-lisp

编辑:解决方案是在第一个(let ...)表单中替换'(1)with(list 1).这是因为我试图修改文字数据.谢谢您的帮助!(我会放弃投票,但显然你需要15点声望......)

这是我在这个网站上的第一篇文章.

我今天解决了一些Project Euler问题,我在Common Lisp中遇到了一些意外的列表排序行为(至少对我来说):

我有一个函数,可以找到数字x的所有正确除数:

(defun divisors (x)
    "Finds all of the proper divisors of x."
    (let ((sq (sqrt x)) (divs '(1)))
        (when (integerp sq) (push sq divs))
        (loop for i from 2 to (1- (floor sq)) do
        (let ((div (/ x i)))
            (when (integerp div)
                (push i divs)
                (push div divs))))
    divs))
Run Code Online (Sandbox Code Playgroud)

这个功能很棒.例如:

(divisors 100)
==> (20 5 25 4 50 2 10 1)
Run Code Online (Sandbox Code Playgroud)

每当我尝试对结果列表进行排序时,就会出现问题:

(sort (divisors 100) #'<)
==> (1 2 4 5 10 20 25 50)
Run Code Online (Sandbox Code Playgroud)

嗯,这很好.但是当我再次召唤除数时会发生什么?

(divisors 100)
==> (20 5 25 4 50 2 10 1 2 4 5 10 20 25 50)
Run Code Online (Sandbox Code Playgroud)

什么?也许如果我尝试不同的号码......

(divisors 33)
==> (11 3 1 2 4 5 10 20 25 50)
Run Code Online (Sandbox Code Playgroud)

在对结果列表进行排序后,先前查询的除数是持久的.如果我重新编译该函数,我会得到没有错误,直到我再次排序结果列表.我假设我已经搞砸了函数定义中的某个地方,但我对Lisp很新,我找不到错误.这可能是嵌套(let ...)表单的问题吗?

提前致谢!

Rai*_*wig 9

经常被问到.

您已修改了文字数据.您需要提供新数据.使用功能LIST或功能进行复印.

  • @Lisper`'(1)`是一个列表文字.对文字使用破坏性操作的后果是未定义的,"sort"是一种破坏性操作.使用`list`函数构造列表. (3认同)