![](/img/trans.png)
[英]In Racket using recursion how do I return #true if a list “L” sums to n but no values in L are duplicated
[英]Return List using recursion with Racket
我正在尝试从具有双重递归的方法返回列表(BST,二进制搜索树)。 我试图实现它如下:
(define (mapBST BST someFunct)
(cond
[(null? BST)
'()]
[else (cons (car BST) (someFunct (car (cdr BST)))) (mapBST (car (cdr (cdr BST))) someFunct) (mapBST (car (cdr (cdr (cdr BST)))) someFunct) ]
)
)
这个小片段代码被调用了
(define bst
'( 3 "3"
( 1 "1"
()
( 2 "2" () ())
)
( 5 "5" () () )
)
)
(mapBST bst string->number)
我也尝试过此代码段,但它返回了[ ((() ()) ())
:
[else (printf (car (cdr BST))) (cons (mapBST (car (cdr (cdr BST))) someFunct) (mapBST (car (cdr (cdr (cdr BST)))) someFunct)) ]
结果应返回相同的BST,但以数字代替字符串作为值。
在else表达式中,您没有正确地重建二进制搜索树,这就是为什么您得到一个空列表的原因。 将您的else
情况更改为
...
[else
(cons (car BST)
(cons (someFunct (car (cdr BST)))
(cons (mapBST (car (cdr (cdr BST))) someFunct)
(cons (mapBST (car (cdr (cdr (cdr BST)))) someFunct) empty))))]
...
要么
...
[else
(list (car BST)
(someFunct (car (cdr BST)))
(mapBST (car (cdr (cdr BST))) someFunct)
(mapBST (car (cdr (cdr (cdr BST)))) someFunct))]
...
将解决您的问题(两个选项都产生相同的列表,因为(cons 1 (cons 2 empty))
等同于(list 1 2)
)。
这是mapBST
的完整更新:
(define (mapBST proc BST)
(cond
[(null? BST) empty]
[else
(list (car BST)
(proc (cadr BST))
(mapBST proc (caddr BST))
(mapBST proc (cadddr BST)))]))
例如,
(define BST '(3 "3" (1 "1" () (2 "2" () ())) (5 "5" () ())))
(mapBST string->number BST)
=> '(3 3 (1 1 () (2 2 () ())) (5 5 () ()))
正如另一个答案所指出的,您实际上并没有返回您认为在else
子句中的else
。 解决该问题将使您的程序正常工作。 但是,这种(car (cdr (cdr ...)))
是人们在1960年代写Lisp的方式,它正确地使Lisp取了一个坏名字,因为它完全不透明。 使用caddr
方法更好,但仅使用少量方法(该语言提供了多少?我不记得了)。 更好的是,如果您的数据从概念上讲是一个列表,则应使用具有诸如first
& second
类的名称的函数,因为它们表明您的实际含义 (如果从概念上讲,您的数据是一棵简陋的树,那么car
&c可能更好)。 但是他们仍然有“本周有多少人”的问题。
正确的解决方案是使用解构和/或模式匹配根据数据的形状绑定变量。 这实际上使您的代码清晰。 Racket为此提供了一个全面的机制,虽然我并不十分详细地了解它,但是我知道足以让我顺利通过。 这是您的函数的(固定)版本,使用match
来完成工作:
(define (map-bst bst fn)
(match bst
['() '()]
[(list 1st 2nd 3rd 4th)
(list 1st
(fn 2nd)
(map-bst 3rd fn)
(map-bst 4th fn))]
[_ (error "botch")]))
(请注意,这可以使用更好的变量名:我不知道结构的各个位的含义)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.