lisp - 为什么 CLISP 在此嵌套循环期间停止响应?

标签 lisp common-lisp

我正在尝试使用以下代码创建某个单词的子序列。当我添加 by k 时,代码停止响应,但如果我将 k 替换为特定数字,它会起作用。发生了什么事?

(let ((c nil)) (loop for k from 0 to (length "abc")
     finally (return c) do (loop for j from 0 to (length "abc") by k 
    do (loop for i from j to (length "abc") do (push (subseq "abc" j i) c))))) 

最佳答案

调试

if I replace k with a particular number, it works

如果将 k 替换为 0 会怎样?

如果您使用典型的约定来格式化此代码,并且可能如果您隔离出有问题的代码的特定部分,将会更有帮助。也就是说,(remove-duplicates …) 不是这里的问题,您可以删除它。使用一些更常规的格式和一些注释,您的代码是:

(remove-duplicates
 (let ((c nil))
   (loop for k from 0 to (length "abc")                  ; k starts at 0
      finally (return c) 
      do (loop for j from 0 to (length "abc") by k       ; looping for j from 0 to something by k
            do (loop for i from j to (length "abc")
                  do (push (subseq "abc" j i) c)))))
 :test 'equal)

如果您尝试loop for j from 0k 的任何值,将会发生什么?你几乎是在说,“从 0 的 j 开始,然后在下一次迭代中将它递增 0……”所以 j 永远不会到达任何地方。这真的可以用 printformat 捕获。我知道这与使用调试器不同,但有时最简单的方法是最快的:

[8]> (remove-duplicates
 (let ((c nil))
   (loop for k from 0 to (length "abc")
      finally (return c) 
      do (loop for j from 0 to (length "abc") by k 
            do
              (format t "~&k: ~a, j: ~a" k j )
              (loop for i from j to (length "abc")
                 do (push (subseq "abc" j i) c)))))
 :test 'equal)
k: 0, j: 0
k: 0, j: 0
k: 0, j: 0
…

收集子序列

如果您尝试收集给定序列的子序列,您可以这样做。这适用于字符串(向量)和列表(尽管它对列表效率较低)。

(defun subsequences (sequence) 
  (loop
     with length = (length sequence)
     for i from 0 to length
     nconcing (loop 
                 for j from (1+ i) to length
                 collecting (subseq sequence i j))))
(subsequences "abc")
;=> ("a" "ab" "abc" "b" "c")

(subsequences '(1 2 3))
;=> ((1) (1 2) (1 2 3) (2) (2 3) (3))


附录:SBCL 的一个难以理解的错误

有趣的是,您会收到 SBCL 的运行时错误,尽管错误消息并没有特别清楚地说明原因。可能和无限循环有关。

* (remove-duplicates
 (let ((c nil))
   (loop for k from 0 to (length "abc")
      finally (return c) 
      do (loop for j from 0 to (length "abc") by k 
            do
              (loop for i from j to (length "abc")
                 do (push (subseq "abc" j i) c)))))
 :test 'equal)

debugger invoked on a TYPE-ERROR in thread #<THREAD "initial thread" RUNNING
                                              {1002978E71}>:
  The value 0
  is not of type
    (OR (SINGLE-FLOAT (0.0)) (DOUBLE-FLOAT (0.0d0)) (RATIONAL (0))).

Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

关于lisp - 为什么 CLISP 在此嵌套循环期间停止响应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23898247/

相关文章:

scheme - Racket 上的回溯问题

concurrency - Common Lisp 并行编程

lisp - 在 Racket 中求和非常大的数字

scheme - 我想了解每一行代码如何删除列表中的重复项,所以这是列表 (a b a a c c) 给出的 (a b)

lisp - 如何在 LISP 中覆盖 (defun eval (expr)) 函数

emacs - 遍历到 Lispworks 中的匹配括号

haskell - Common LISP 中的数字类型边界和 GHCI 中流过的 Stack

lisp - 在 Lisp 中,代码就是数据。这有什么好处?

lisp - Lisp 中的反引号扩展

lisp - 尝试返回当前列表中偶数位置的值列表