2012-10-01 29 views
1

我得到了一个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 '(a a a b b b b c)) 
(b . 4) 

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

+0

为什么不使用调试TRACE,步骤或打印参数的函数? –

+0

在实际使用之前,我还没有听说过这些功能。我会看看他们。 – category

+0

本书解释了基本知识:http://www.cs.cmu.edu/~dst/LispBook/ –

回答

6

我已经意识到我的错误了。

看着我测试,而不是

(null (cdr lst)) 

我应该有

(null (remove (car lst) lst)) 

从而使多余的,较少出现的独特元素被移除。

+0

你能解释一下你如何在这里使用'trace'(它会以帮助其他用户的方式完成答案)?此外,由于这回答了你的问题,请[接受它](http://meta.stackexchange.com/q/5234/225437)! –

+0

我已经删除了'跟踪'输出,因为我无法调和输出的含义与代码。 – category

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)) 
+1

你可以使用这个:'(incf(gethash i hash 0))' –

+0

谢谢,这个函数包含了很多新的概念 - 我会简短地讨论哈希表,所以这将是一个很好的例子。 – category