我正在尝试使用以下代码创建某个单词的子序列。当我添加 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 0
到 k
的任何值,将会发生什么?你几乎是在说,“从 0 的 j 开始,然后在下一次迭代中将它递增 0……”所以 j 永远不会到达任何地方。这真的可以用 print
或 format
捕获。我知道这与使用调试器不同,但有时最简单的方法是最快的:
[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/