递归计数以数字开头的子列表

时间:2016-07-27 05:23:33

标签: common-lisp

我试图在Lisp中编写代码,以递归方式从number开始计数子列表。我试图使用mov r10d, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB ,但是当我的代码到达一个原子时,它不会计算列表的其余部分。

我的代码在这里,

numberp

我可以得到一个子列表的数量但是当到达一个原子时,它不计算其余的。

(defun nombres (liste) 
  (cond 
   ((atom liste) 0)((atom (car liste)) 0) 
   ((and (numberp (caar liste)) (+ (nombres (cdr liste)) 1)))
   (t (nombres (cdr liste))) ) )

当我用(listp(汽车列表))测试子列表时,它给我零。

[67]> (nombres '((a b d) (5 g) (7 m)))
2
[68]> (nombres '((a b d) (5 g) g (7 m)))
1

我希望得到类似的内容:

[69]> (defun nombres (liste) 
  (cond 
   ((atom liste) 0)((atom (car liste)) 0) 
   ((listp (car liste))(and (numberp (caar liste)) (+ (nombres (cdr liste)) 1)))     (t (nombres (cdr liste))) ) )
NOMBRES
[70]> (nombres '((a b d) (5 g) g (7 m) m))
NIL

感谢您的帮助

2 个答案:

答案 0 :(得分:2)

您需要考虑需要处理的案例。

  1. 列表的结尾=>返回结果
  2. 前面有一个数字的子列表=>在结果中添加一个
  3. 其他=>继续下一个元素
  4. 这些很容易转换为COND

    (cond ((endp list) ...)            ; 1
          ((and (listp (car list))     ; 2
                (numberp (caar list)))
           ...)
          (t ...)                      ; 3
    

    使用累加器作为可选参数,计数很容易填写:

    (defun count-sublists (list &optional (acc 0))
      (cond ((endp list) acc)
            ((and (listp (car list))
                  (numberp (caar list)))
             (count-sublists (cdr list) (1+ acc)))
            (t (count-sublists (cdr list) acc))))
    
    (count-sublists '((a b d) a (5 g) (b) (7 m) j (8 h l g)))
    ;=> 3
    

答案 1 :(得分:1)

标准Common Lisp函数count-if更易于使用:

CL-USER > (count-if (lambda (item)
                      (and (consp item)
                           (numberp (first item))))
                    '((a b d) a (5 g) (b) (7 m) j (8 h l g)))
3