所以我现在被困在一个“简单?”在Racket中的功能。它正在使用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放置不正确。有什么想法吗?
答案 0 :(得分:3)
它比你想象的要复杂一些。您可能已经注意到,我们必须删除输出列表中的重复元素。为此,最好定义一个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)))
以上可能会以不同的顺序返回并输出列表,但这样可以。在你问之前:是的,我们做需要帮助函数。如果没有它,请不要求解决方案......
答案 1 :(得分:0)
一个简单,独立的解决方案是:
(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
。