2012-10-01 31 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