【问题标题】:Common Lisp - Function which return an element appears n times in a listCommon Lisp - 返回元素的函数在列表中出现 n 次
【发布时间】:2020-04-19 06:55:46
【问题描述】:

我正在尝试编写一个函数,它返回一个元素在列表中出现 n 次。

例如,对于像:(setq lst '(a b b b c)) 这样的列表,函数返回:

count-list (lst 3) --> b

但是当有两个元素(或更多)同时出现在 n 中时,函数只返回第一个元素:

count-list (lst 1) --> a

代替

count-list (lst 1) --> a b

这里是函数:

(defun count-list (lst nb)
    (loop for x in lst do
        (if (eq (count x lst) nb)
            (return x)
            )
        )
    )

我错过了什么?

【问题讨论】:

    标签: lisp common-lisp


    【解决方案1】:

    return 告诉 count-list 函数一旦找到命中就立即退出,因此它不会寻找与计数匹配的其他元素。 一种可能的解决方案是:

    (defun count-list (lst n) 
      (remove-duplicates 
        (mapcan #'(lambda (x) 
                    (when (eql (count x lst) n) 
                      (list x) )) 
             lst )))
    

    但是,这是非常低效的,因为对于每个项目,必须遍历列表两次,一次用于函数本身,一次用于计数,因此这将花费与列表长度的平方成正比的时间。
    一种更有效的方法是累积值(例如在关联列表中)并在最后选择与输入计数匹配的那些项目。

      (defun count-list (lst n)
        (let* (count-list pair)
          (dolist (x lst)
            (if (setq pair (assoc x count-list))
              (incf (cdr pair))
              (push (cons x 1) count-list) ))
          (mapcan #'(lambda (pair) 
                      (when (eql n (cdr pair))
                         (list (car pair)) )) 
                  count-list )))
    

    【讨论】:

      【解决方案2】:

      我从未使用过 LISP。我假设您的问题是您的函数在第一次匹配时返回。要么在你的函数中创建一个数组来存储所有出现 n 次的元素并返回到该数组,或者,例如,在 Python 中我会使用 print(x) 这样函数不会在第一次匹配时返回,就像你的情况一样。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-01
        • 2020-08-16
        • 1970-01-01
        • 1970-01-01
        • 2014-11-28
        • 2013-03-26
        相关资源
        最近更新 更多