You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何升级Lisp单元素统计函数,实现列表所有元素出现次数统计

解决列表元素批量统计的问题

嘿,你已经搞定了单个元素的统计函数,现在要扩展成一次性统计a、b、c、d所有元素的出现次数对吧?我给你两种方案,按需选择~

方案一:复用现有函数快速实现

既然你已经有了stejem这个单个元素统计的工具,那最直接的方式就是分别调用它统计每个目标元素,再把结果打包成你想要的格式:

; 先保留你已有的单个元素统计函数
(defun stejem (a L) 
  (cond ((null L) 0) 
        ((equal a (car L)) (+ 1 (stejem a (cdr L)))) 
        (t (stejem a (cdr L)))))

; 新增批量统计函数,针对a、b、c、d
(defun stejem-vse (L)
  (list (list 'a (stejem 'a L))
        (list 'b (stejem 'b L))
        (list 'c (stejem 'c L))
        (list 'd (stejem 'd L))))

; 测试调用
(print (stejem-vse '(a b c b b a c d)))

运行这段代码,输出正好是你期望的:((a 2)(b 3)(c 2)(d 1))。这个方案的优点是简单直接,完全复用你已有的代码,不需要重新理解复杂逻辑;缺点是如果列表很大,每个元素都要遍历一次列表,效率会稍低。

方案二:一次遍历高效统计

如果你的列表可能比较大,更高效的方式是只遍历一次列表,同时完成所有元素的统计。这里用递归+辅助函数的方式实现:

(defun count-all (L)
  ; 定义辅助函数,用于更新某个元素的计数
  (labels ((update-count (item counts)
             (cond 
               ; 如果计数列表为空,直接添加这个元素的初始计数1
               ((null counts) (list (list item 1)))
               ; 如果找到目标元素,把计数加1
               ((equal item (caar counts))
                (cons (list item (+ 1 (cadar counts))) (cdr counts)))
               ; 没找到就继续递归处理剩下的计数
               (t (cons (car counts) (update-count item (cdr counts)))))))
    (cond 
      ((null L) '()) ; 列表为空时返回空
      ; 递归处理列表剩余部分,再更新当前元素的计数
      (t (update-count (car L) (count-all (cdr L)))))))

; 如果需要严格按照a、b、c、d的顺序输出,再套一层整理函数
(defun count-all-ordered (L)
  (let ((counts (count-all L)))
    (list (assoc 'a counts)
          (assoc 'b counts)
          (assoc 'c counts)
          (assoc 'd counts))))

; 测试调用
(print (count-all-ordered '(a b c b b a c d)))

这个版本只需要遍历一次列表,效率更高。count-all会返回所有元素的统计结果(顺序是元素最后出现的顺序),count-all-ordered则会把结果按a、b、c、d的顺序整理好,输出和你期望的完全一致。

内容的提问来源于stack exchange,提问作者PabloEscobar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:14:34