繁体   English   中英

使用Racket递归返回列表

[英]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方法更好,但仅使用少量方法(该语言提供了多少?我不记得了)。 更好的是,如果您的数据从概念上讲是一个列表,则应使用具有诸如firstsecond类的名称的函数,因为它们表明您的实际含义 (如果从概念上讲,您的数据是一棵简陋的树,那么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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM