LISP中的计数器变量

Adi*_*ala 1 lisp math common-lisp

定义带有列表L和符号A的函数'occ',并计算L中符号A的出现.例如:(occ'(((s)o)d)'f) - > 0

到目前为止我得到了什么:

(defun occ(list a)
(setq counter 0)
  ;Checks if the given list is has an nested list
  (if (consp list)
    ; Breaking the list down atom by atom and recursing
    (or (occ a (car list))
        (occ a (cdr list)))
    ; checks if symbols are the same
    (if(eq a list)
        (setq counter(1+ counter)))))
Run Code Online (Sandbox Code Playgroud)

但是我的输出继续说Nil而不是显示计数器值.我不能使用任何更高级别的LISP功能.

cor*_*ump 6

首先,不要在sett函数中使用setq进行变量初始化,使用let.其次,让我们看看为什么你做错了,你的代码:

(defun occ(list a)
(setq counter 0) ;; You always setting counter to 0 on new
                 ;; level of recursion
  (if (consp list)
   (or (occ a (car list))  ;; You reversed arguments order?
        (occ a (cdr list))) ;; according to your definition it must be
                            ;; (occ (car list) a)
    (if(eq a list)
        (setq counter(1+ counter)))))
Run Code Online (Sandbox Code Playgroud)

无论如何,你不需要任何计数器变量来做你想要的.

正确的函数可能看起来像这样(我改变了参数顺序,因为我在LIST中找到SYMBOL看起来更好):

(defun occ (sym nested-list)
  (cond
    ((consp nested-list)
     (+ (occ sym (car nested-list)) (occ sym (cdr nested-list))))
    ((eq sym nested-list) 1)
    (t 0)))

CL-USER> (occ 'x '(((s) o ((f ()) f)) d))
0

CL-USER> (occ 'f '(((s) o ((f (x (((f))))) f)) d f))
4
Run Code Online (Sandbox Code Playgroud)