【问题标题】:Finding the occurence element in the list in racket在球拍列表中查找出现元素
【发布时间】:2014-07-09 04:39:29
【问题描述】:

假设(list "apple" "orange" "apple" "grape" "orange")并产生(list (list 2 "apple") (list 2 "orange") (list 1 "grape"))。

最常见的水果将首先出现在生产的列表中。 在平局的情况下,按字母顺序将平局对与水果进行排序。

在本地使用map、filter、foldr、quicksort等抽象列表功能。没有递归。

如果没有递归,我不知道该怎么做。

我是这样写的:

(define (function list)
   (cond
      [(empty? list) empty]
      [else
        (local
           (define (helper1 a b)
             (cond
               [(equal? a b) a]
               [else b]))
           (define T (foldr helper1 (first list) (rest list)))
           (define (count a)
             (cond
               [(equal? a T) true]
               [else false]))
           (define new-list (quicksort (length (filter count list)) >))]

【问题讨论】:

  • 到目前为止,您尝试了什么?请张贴代码
  • 您意识到map、filter 和foldr 在幕后为您执行循环(或递归),对吗?这就是你在没有(手动)递归的情况下如何做到的。
  • 这里有一个关于如何解决这个问题的提示。首先,以某种方式实现bagify。然后交换每个元素的顺序(因为bagify 将项目放在第一位,计数放在第二位),然后对元素进行排序。
  • 我刚刚发布了我的代码,问题是我只能获取一个元素,而不是全部,因为不允许递归。

标签: list sorting recursion scheme racket


【解决方案1】:

最有效的方法是使用(可变)哈希表:

(define (count-by-type lst)
  ; create hash
  (define h (make-hash))
  ; update hash, creating entries if needed, otherwise adding 1 to existing entry
  (map (lambda (e) (hash-update! h e add1 0)) lst) 
  ; create list of (count key) elements from hash and sort accordingly
  (sort (map (lambda (e) (list (cdr e) (car e))) (hash->list h))
        (lambda (x y) (or (> (car x) (car y)) 
                          (and (= (car x) (car y)) (string<? (cadr x) (cadr y)))))))

测试:

> (count-by-type (list "apple" "orange" "apple" "grape" "orange"))
'((2 "apple") (2 "orange") (1 "grape"))

【讨论】:

    【解决方案2】:

    我刚刚重新整理了我的own answer from a previous question。这似乎是一个类似的任务,但没有struct

    使用哈希,您只需遍历未排序的列表,然后生成一个列表,然后使用特殊的&lt;-函数进行排序,该函数按计数排序,然后是水果。

    这些提示适用于功能性解决方案。首先对参数(sort list-of-fruits string&gt;?) 进行排序。 按降序与您的结果相反。 .

    鉴于列表至少有一个元素:

    (let rec ((cur (car sorted-fruits)) (cnt 1) (lst (cdr sorted-fruits)) (acc '()))
      (cond ((equal? cur (car lst)) (rec cur (add1 cnt) (cdr lst) acc))
            (else (rec (car lst) 1 (cdr lst) (cons (list cnt cur) acc)))))
    

    这将产生一个列表升序计数。

    如果再次排序:

    (sort list-of-counts-and-fruit (lambda (x y) (>= (car x) (car y)))
    

    Racket 中的sort 稳定。这意味着如果您在列表中有两个相同的数量,它们将以原始顺序结束。原始顺序是动物升序,因此结果按计数降序排列,然后按名称升序排列。

    我猜你的过程可以通过将它们链接在一起来制作,也许使用let 来存储中间体以使表达式更短且更具可读性。

    【讨论】:

      猜你喜欢
      • 2018-03-04
      • 1970-01-01
      • 1970-01-01
      • 2015-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多