【问题标题】:Abstract List Functions in Racket/Scheme - Num of element occurrences in listRacket/Scheme 中的抽象列表函数 - 列表中元素出现的次数
【发布时间】:2015-01-13 20:36:29
【问题描述】:

所以我目前停留在“简单?”球拍中的功能。它使用的是 lambda 语言的中级学生。

对此的一些限制是不允许递归,本地函数也不允许。它是简单明了的抽象列表函数。

这个函数应该做的是接受一个数字列表,并输出一个对列表,其中每个对都有第一个元素作为数字,第二个元素是它在列表中出现的数字。

例子:

   (1 1 2 3) => ((1 2) (2 1) (3 1))
   (2 3 4 3) => ((2 1) (3 2) (4 1))

我有一个函数,它通过输入一个数字列表和一个数字来生成出现次数:

(define (occurrences lon n)
    (length (filter (lambda (x) (= x n)) lon)))

我的做法显然是错误的:

(define (num-pairs-occurrences lon)
    (list (lambda (x) (map (occurrences lon x) (remove x lon)) x))

我认为上述方法可行,但显然我的 lambda 放置不正确。有什么想法吗?

【问题讨论】:

    标签: list lambda scheme racket


    【解决方案1】:

    这比你想象的要复杂一些。您可能已经注意到,我们必须删除输出列表中的重复元素。为此,我们最好定义一个 remove-duplicates 辅助函数(也使用抽象列表函数)——事实上,这很常见,是 Racket 中的一个内置函数,但在您当前的语言设置中不可用:

    (define (remove-duplicates lst)
      (foldr (lambda (e acc)
               (if (member e acc)
                   acc
                   (cons e acc)))
             '()
             lst))
    

    现在使用抽象列表函数很容易组合解决方案:

    (define (num-pairs-occurrences lon)
      (map (lambda (e) (list e (occurrences lon e)))
           (remove-duplicates lon)))
    

    上面可能会以不同的顺序返回和输出列表,但这没关系。在你问之前:是的,我们确实需要那个辅助函数。请不要在没有它的情况下寻求解决方案...

    【讨论】:

    • OP 表示不允许递归,因此 remove-duplicates 的定义(如果它在该语言中尚不可用)将不受限制。
    • 我设法创建了一个类似于您的 remove-duplicates 的函数,除了没有递归。所以它现在完美运行。谢谢!之后我对如何实现从列表中删除元素感到困惑。
    • @E46 我用remove-duplicates 的无递归实现更新了我的答案。我希望这就是你要找的,恕我直言,老师不应该用这些人为的问题来限制学生,在现实生活中你可以使用语言中可用的任何工具来解决问题
    • 是的,这就是我要找的。另外,是的,我相信完全相同。但从某种意义上说,它有助于建立对抽象列表函数的理解和应用,因为老实说我会使用递归,因为它更简单、更容易做到。
    【解决方案2】:

    一个简单的、独立的解决方案是:

    (define (num-pairs-occurences lst)
      (foldl (lambda (e r) 
               (if (or (null? r) (not (= (caar r) e)))
                   (cons (list e 1) r)
                   (cons (list e (add1 (cadar r))) (cdr r))))
             null
             (sort lst >)))
    

    基本上,您首先对列表进行排序,然后将其折叠起来。如果你得到的元素 (e) 与结果列表 (r) 的第一个元素相同,则增加计数,否则将新的子列表添加到 r。

    如果您按>(降序)排序,您实际上可以使用更节省内存的foldl。如果按<(升序)排序,则需要使用效率较低的foldr

    【讨论】:

      猜你喜欢
      • 2015-01-08
      • 2011-08-10
      • 1970-01-01
      • 2012-04-05
      • 2018-10-08
      • 1970-01-01
      • 1970-01-01
      • 2020-06-09
      相关资源
      最近更新 更多