Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Recursion 使用带Racket的递归返回列表_Recursion_Lisp_Racket_Binary Search Tree - Fatal编程技术网

Recursion 使用带Racket的递归返回列表

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

我试图从一个具有双重递归的方法返回一个列表(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
无效-忽略它们的值,只返回最后一个值。