【问题标题】:stack overflow when executing recursive lisp function执行递归lisp函数时堆栈溢出
【发布时间】:2012-10-01 09:27:23
【问题描述】:

当我尝试执行以下递归函数时,我在 clisp 中收到“-程序堆栈溢出”提示,我相信该函数会返回列表中最常见的元素:

(defun greater-member (lst)
  (cond  ((null (cdr lst))
                (cons (car lst) (count-if #'(lambda (x) (eql x (car lst))) lst)))
         ((>= (count-if #'(lambda (x) (eql x (car lst))) lst)
              (count-if #'(lambda (x) (eql x (car (remove (car lst) lst)))) lst))
                (greater-member (remove (car (remove (car lst) lst)) lst)))
         (t (greater-member (remove (car lst) lst)))))

例如 greater-number 应该返回如下:

>(greater-number '(a a a b b b b c))
(b . 4)  

请问,是什么原因导致溢出?我已经摆脱了所有的小语法错误 通过在 clisp 中重复执行 greater-number,该函数似乎在逻辑上成立。

【问题讨论】:

  • 为什么不使用 TRACE、STEP 或打印参数来调试函数?
  • 其实我没听说过这些功能。我会看看他们。
  • 这本书解释了基础知识:cs.cmu.edu/~dst/LispBook
  • 谢谢 - 我现在已经意识到了这个错误,使用 TRACE。也谢谢你的链接。
  • (count-if #'(lambda (x) (eql x (car lst))) lst) is (count (car lst) lst)

标签: recursion lisp common-lisp stack-overflow clisp


【解决方案1】:

我现在意识到我的错误了。

查看我的 null 测试,而不是

(null (cdr lst)) 

我应该有

(null (remove (car lst) lst))

这样就删除了多余的、较少出现的唯一元素。

【讨论】:

  • 你能解释一下你是如何在这里使用trace的吗(它会以一种有助于其他用户的方式完成答案)?另外,既然这回答了你的问题,请accept it
  • 我删除了“跟踪”输出,因为我无法将输出的含义与代码相协调。
【解决方案2】:

稍微优化一点的版本:

(defun most-common (list)
  (let* ((len 0) (hash (make-hash-table))
         (max-occurences 0)
         key
         (max-possible
          (dolist (i list (ceiling len 2))
            (incf (gethash i hash 0))
            (incf len))))
    (maphash #'(lambda (a b)
                 (if (>= b max-possible)
                     (return-from most-common
                       (if (> b max-occurences) a key))
                     (progn
                       (when (> b max-occurences)
                         (setf key a max-occurences b))
                       (decf max-possible (max 1 (floor b 2))))))
             hash) key))

【讨论】:

  • 你也许可以使用这个:(incf (gethash i hash 0))
  • 谢谢,这个函数包含了很多新概念—​​—我会简短地介绍哈希表,所以这将是一个很好的例子。
猜你喜欢
  • 2013-02-22
  • 2017-10-20
  • 2018-05-28
  • 2011-02-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多