【问题标题】:Count elements and return them计算元素并返回它们
【发布时间】:2017-12-01 09:34:42
【问题描述】:

我想计算列表中的元素并返回一个列表,其中包含与它们对应数量配对的元素

类似的东西:

输入: (count-elements '(a b d d a b c c b d d))

输出: ((a 2) (b 3) (d 4) (c 2))

我该怎么做?我尝试将元素及其会计配对没有任何成功

【问题讨论】:

  • 您应该将之前的努力添加到问题中。也许你会更详细地了解究竟是什么导致了你的问题。 :)
  • 如果给你((a 1) (b 3) (d 4) (c 2))和符号a,你将如何生成一个新列表((a 2) (b 3) (d 4) (c 2))

标签: lisp common-lisp


【解决方案1】:

您的问题可以分为三大块:

  1. 重复识别/删除:这可以通过删除每个元素的所有重复项或通过知道当前元素是重复项(因此不将其计为新元素)来完成。这(前一种策略)可以通过使用函数remove-duplicates来完成
  2. 计数:一种实际计数元素的方法。这可以通过函数count 来完成
  3. 组合:一种将结果组合成列表的方法。这可以通过宏 push 来完成。

代码:

(defun count-elements (lst)
  (loop for i in (remove-duplicates lst)
        with ans = nil
        do (push (list i (count i lst)) ans)
        finally (return ans)))

CL-USER> (count-elements '(a a b c))
((C 1) (B 1) (A 2))
CL-USER> (count-elements '(a b c d d a b s a c d))
((D 3) (C 2) (A 3) (S 1) (B 2))
CL-USER> 

注意:由于remove-duplicates返回的值,结果可能与您预期的不一样


编辑: 正如 coredump 所指出的,count-elements 的更好版本是:

(defun count-elements (lst)
  (map 'list
       (lambda (e)
         (list e (count e lst)))
       (remove-duplicates lst)))

其中不使用loop,而是使用map

【讨论】:

  • 如果使用remove-duplicates,组合可以表示为一张图:(map 'list (lambda (e) (list e (count e sequence))) (remove-duplicates sequence))
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-26
  • 2021-11-04
  • 2019-04-22
  • 2022-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多