简体   繁体   English

球拍/方案中的抽象列表功能-列表中元素出现的数量

[英]Abstract List Functions in Racket/Scheme - Num of element occurrences in list

So I'm currently stuck on a "simple?" 所以我目前停留在“简单”上? function in Racket. 在球拍中发挥作用。 It's using the Intermediate Student with lambda language. 它使用具有lambda语言的中级学生。

Some restrictions on this are that NO recursion is allowed, neither are local functions. 对此的一些限制是不允许递归,本地函数也不可以。 It's plain and simple abstract list functions. 它是简单明了的抽象列表函数。

What this function is supposed to do is to take in a list of numbers, and output a list of pairs in which each pair has the first element as the number with the second element being the number it has occurred in the list. 该函数应该做的是获取一个数字列表,并输出一个对列表,其中每个对都具有第一个元素作为数字,而第二个元素是列表中已出现的数字。

Examples: 例子:

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

I have a function that produces the number of occurrences by inputting a list of numbers and a number which is: 我有一个通过输入数字列表和一个数字来产生出现次数的函数:

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

My approach, which was clearly wrong was: 我的方法显然是错误的:

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

I thought the above would work, but apparently my lambda isn't placed properly. 我以为上面的方法可以工作,但是显然我的lambda放置不正确。 Any ideas? 有任何想法吗?

It's a bit trickier than you imagine. 这比您想象的要棘手。 As you've probably noticed, we must remove duplicate elements in the output list. 您可能已经注意到,我们必须在输出列表中删除重复的元素。 For this, is better that we define a remove-duplicates helper function (also using abstract list functions) - in fact, this is so common that is a built-in function in Racket, but not available in your current language settings: 为此,最好定义一个remove-duplicates辅助函数(也使用抽象列表函数)-实际上,它是如此普遍,是Racket中的内置函数,但是在您当前的语言设置中不可用:

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

Now it's easy to compose the solution using abstract list functions: 现在,可以使用抽象列表功能轻松组合解决方案:

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

The above might return and output list in a different order, but that's all right. 上面的返回和输出列表的顺序可能不同,但是没关系。 And before you ask: yes, we do need that helper function. 在您提出以下要求之前:是的,我们确实需要该辅助功能。 Please don't ask for a solution without it... 请不要没有它的解决方案...

An easy, self-contained solution would be: 一个简单,独立的解决方案是:

(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 >)))

Basically, you sort the list first, and then you fold over it. 基本上,您首先对列表进行排序,然后将其折叠。 If the element (e) you get is the same as the first element of the result list (r), you increment the count, otherwise you add a new sublist to r. 如果获得的元素(e)与结果列表(r)的第一个元素相同,则增加计数,否则将新的子列表添加到r。

If you sort by > (descending), you can actually use foldl which is more memory-efficient. 如果按> (降序)排序,则实际上可以使用foldl ,这样可以提高内存效率。 If you sort by < (ascending), you need to use foldr which is less efficient. 如果按< (升序)排序,则需要使用效率较低的文件foldr

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM