Recursion 使用带Racket的递归返回列表
我试图从一个具有双重递归的方法返回一个列表(BST,一个二进制搜索树)。我正在尝试按如下方式实施:Recursion 使用带Racket的递归返回列表,recursion,lisp,racket,binary-search-tree,Recursion,Lisp,Racket,Binary Search Tree,我试图从一个具有双重递归的方法返回一个列表(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))))
(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))))]
...
或
将解决您的问题(两个选项产生相同的列表,因为(cons 1(cons 2 empty))
相当于(list 1 2)
)
以下是mapBST
的完整更新:
[else (printf (car (cdr BST))) (cons (mapBST (car (cdr (cdr BST))) someFunct) (mapBST (car (cdr (cdr (cdr BST)))) someFunct)) ]
(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
子句中的内容。修复它将使您的程序正常工作。然而,这种(car(cdr(cdr…))
的东西是人们在20世纪60年代编写Lisp的方式,它正确地得到了Lisp的坏名声,因为它是完全不透明的。使用像caddr
这样的东西会更好,但只是稍微好一点(该语言提供了多少功能?我记不起来了)。更好的是,如果您的数据在概念上是一个列表,则使用名为first
和second
的函数,因为它们说明了您的实际意思(如果您的数据在概念上是一个conses树,那么car
&c可能更好)。但他们仍然存在“本周有多少人”的问题
正确的解决方案是使用解构和/或模式匹配根据数据的形状绑定变量。这使您的代码实际上非常清晰。球拍对此有一个全面的机制,我不太了解细节,但我知道的足够让我通过。以下是您的函数的(固定)版本,它使用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")]))
(请注意,这可能需要更好的变量名:我不知道结构的各个位意味着什么)。显示您正在调用的代码、它产生的内容以及您希望它产生的内容。正确缩进代码,在新行上启动每个子表达式。提示:在
[else A B C]
中,A
和B
无效-忽略它们的值,只返回最后一个值。