执行递归lisp函数时堆栈溢出

时间:2012-10-01 09:27:24

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

当我尝试执行以下递归函数时,我在clisp中得到'-Program stack overflow'提示符,我相信它会返回列表中最常见的元素:

(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 '(a a a b b b b c))
(b . 4)  

请问,导致溢出的原因是什么?我已经摆脱了所有的小语法错误 通过在clisp中重复执行更大数字,该函数似乎在逻辑上保持不变。

2 个答案:

答案 0 :(得分:6)

我现在意识到自己的错误。

查看我的 null 测试,而不是

(null (cdr lst)) 

我应该

(null (remove (car lst) lst))

这样就可以删除多余的,较少发生的独特元素。

答案 1 :(得分:1)

更优化的版本:

(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))