【问题标题】:Counting numbers or characters in list in Scheme计算 Scheme 中列表中的数字或字符
【发布时间】:2012-12-05 12:36:34
【问题描述】:

有谁知道如何计算列表中的所有数字或字符并以这种格式成对打印:(number . number_of_occurrences)。例如:

(计数'(3 1 3 2 1 2 3 3 3))

((3 . 5) (1 . 2) (2 . 2))

(count '(d b a c b b a))

((d.1)(b.3)(a.2)(c.1))

提前感谢您帮助我:)

【问题讨论】:

    标签: list lisp scheme counting


    【解决方案1】:

    这是一个想法 - 使用哈希表来跟踪出现次数。这是一个O(n) 过程:

    (define (counter lst)
      (let ((counts (make-hash)))
        (let loop ((lst lst))
          (cond ((null? lst)
                 (hash->list counts))
                (else
                 (hash-update! counts (car lst) add1
                               (lambda () 0))
                 (loop (cdr lst)))))))
    

    另外,这是@mobyte 在 Scheme 中的解决方案的一个更简单的版本(它不使用 filter) - 请注意这是O(n^2),因此效率低于基于哈希表的过程:

    (define (counter lst)
      (map (lambda (e)
             (cons e (count (curry equal? e) lst)))
           (remove-duplicates lst)))
    

    无论哪种方式,它都按预期工作:

    (counter '(3 1 3 2 1 2 3 3 3))
    => '((3 . 5) (2 . 2) (1 . 2))
    
    (counter '(d b a c b b a))
    => '((b . 3) (a . 2) (d . 1) (c . 1))
    

    【讨论】:

      【解决方案2】:

      这是 clojure 中的解决方案。但我希望它会有所帮助:

      (defn counter [l]
        (map (fn [e]
               [e (count (filter #{e} l))])
             (distinct l)))
      
      (counter [3 1 3 2 1 2 3 3 3])
      -> ([3 5] [1 2] [2 2])
      
      (counter '(d b a c b b a))
      -> ([d 1] [b 3] [a 2] [c 1])
      

      【讨论】:

      • 公平地说,在 Clojure 中,只需执行 (frequencies [:a :a :b :c :c]) 并得到 {:a 2, :b 1, :c 2}
      • @JasonLewis 很高兴知道。初衷只是为了展示一个算法的思路。
      猜你喜欢
      • 2017-03-12
      • 2019-03-19
      • 2017-05-30
      • 2013-10-14
      • 2018-05-12
      • 2018-11-07
      • 2017-07-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多