Scheme中的这两个问题你是怎么做的???
usage: (twice square)
=> #<procedure>
usage: ((twice square) 2)
=> 16
usage: ((twice (twice square)) 10)
=> 10000000000000000
usage: (member 4 (list 1 2 4))
=> #t
usage: (insert 4 (list 1 2))
=> (4 1 2)
我已经为问题 2 尝试了下面的代码(但它没有按照我想要的方式工作),而且 hHow 不知道问题 1
(define (set? lst)
(cond ((null? lst) #t)
((member? (car lst) (cdr lst)) #f)
(else (set? (cdr lst)))))
define
. 例如,map
将过程(在 Racket 中,函数称为过程)作为第一个参数,并在列表的每个元素上调用该过程:> (map add1 '(1 2 3 4 5))
'(2 3 4 5 6)
> (map sub1 '(1 2 3 4 5))
'(0 1 2 3 4)
想象一下,您希望使用 将每个数字增加 2 map
。您可以为此定义命名函数:
(define (add2 x) (+ x 2))
> (map add2 '(1 2 3 4 5))
'(3 4 5 6 7)
或使用lambda
,它创建匿名函数:
> (map (lambda (x) (+ x 2))
'(1 2 3 4 5))
'(3 4 5 6 7)
这个函数不能从你程序的其他地方调用(除非你把它绑定到某个符号上)并且在使用后被丢弃。
由创建的函数lambda
也可以作为结果返回。也许你经常需要添加一些数字,你不想(lambda (x) ... )
每次都写。所以,你可以写这样的函数:
(define (adder y)
(lambda (x) (+ x y)))
并将其用于map
:
> (map (adder 3) '(1 2 3 4 5))
'(4 5 6 7 8)
> (map (adder 4) '(1 2 3 4 5))
'(5 6 7 8 9)
请注意,创建的匿名函数会记住,即y = 3
或y = 4
。实际上,Racket 中的所有函数都是词法闭包,它们会记住它们的创建位置以及在那一刻绑定了哪些符号。
因此,您的解决方案将使用以下原则:
(define (square x)
(* x x))
(define (twice f)
(lambda (x) (f (f x))))
那么,((twice (twice square)) 10)
可以改写为
> ((lambda (x) ((lambda (x) (square (square x)))
((lambda (x) (square (square x)))
x))) 10)
10000000000000000
那是 10^16。
> (= ((twice (twice square)) 10)
(expt 10 16))
#t
member
and之外的其他函数insert
,因为在您的示例中,它们在列表中被调用并且没有list->set
明确提到任何函数。函数member
必须重命名,如下所示:
(define (my-member v lst)
(cond ((null? lst) #false)
((= v (car lst)) #true)
(else (my-member v (cdr lst)))))
(内置函数member
实际上返回列表,但这已经足够了。)
使用insert
,您必须检查您的列表是否已经包含该元素,在这种情况下,按原样返回。
(define (insert v lst)
(if (my-member v lst)
lst
(cons v lst)))
例子:
> (insert 3 '(1 2 3))
'(1 2 3)
> (insert 4 '(1 2))
'(4 1 2)
您可能还会发现check-duplicates
并且remove-duplicates
很有用,并且已经有用于处理集合的Racket 库。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句