简体   繁体   English

使用Racket递归返回列表

[英]Return List using recursion with Racket

I am trying to return a list (BST, a binary search tree) from a method that has double recursion. 我正在尝试从具有双重递归的方法返回列表(BST,二进制搜索树)。 I am trying to implement it as follow: 我试图实现它如下:

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

  )
)

This gets called with this little snippet of code 这个小片段代码被调用了

(define bst 
             '( 3 "3"
                  ( 1 "1"
                     ()
                     ( 2 "2" () ())
                  )
                  ( 5 "5" () () )
            )
) 
(mapBST bst string->number)

I also tried this snippet but it returned ((() ()) ()) : 我也尝试过此代码段,但它返回了[ ((() ()) ())

[else (printf (car (cdr BST))) (cons (mapBST (car (cdr (cdr BST))) someFunct) (mapBST (car (cdr (cdr (cdr BST)))) someFunct)) ]

The result should return the same BST but with number instead of string as the value. 结果应返回相同的BST,但以数字代替字符串作为值。

Within your else-expression, you are not properly reconstructing the binary search tree, which is why you are getting an empty list. 在else表达式中,您没有正确地重建二进制搜索树,这就是为什么您得到一个空列表的原因。 Changing your else case to 将您的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))))]
...

or 要么

...
[else
 (list (car BST)
       (someFunct (car (cdr BST)))
       (mapBST (car (cdr (cdr BST))) someFunct)
       (mapBST (car (cdr (cdr (cdr BST)))) someFunct))]
...

will fix your problem (both options produce the same list, since (cons 1 (cons 2 empty)) is equivalent to (list 1 2) ). 将解决您的问题(两个选项都产生相同的列表,因为(cons 1 (cons 2 empty))等同于(list 1 2) )。

Here is a full update of mapBST : 这是mapBST的完整更新:

(define (mapBST proc BST)
  (cond
    [(null? BST) empty]
    [else
     (list (car BST)
           (proc (cadr BST))
           (mapBST proc (caddr BST))
           (mapBST proc (cadddr BST)))]))

For example, 例如,

(define BST '(3 "3" (1 "1" () (2 "2" () ())) (5 "5" () ())))
(mapBST string->number BST)
=> '(3 3 (1 1 () (2 2 () ())) (5 5 () ()))

As pointed out in another answer, you are not actually returning what you think you are in the else clause. 正如另一个答案所指出的,您实际上并没有返回您认为在else子句中的else Fixing that will make your program work. 解决该问题将使您的程序正常工作。 However this kind of (car (cdr (cdr ...))) thing is how people used to write Lisp in the 1960s, and it rightly got Lisp a bad name because it is utterly opaque. 但是,这种(car (cdr (cdr ...)))是人们在1960年代写Lisp的方式,它正确地使Lisp取了一个坏名字,因为它完全不透明。 Using things like caddr is better, but only slightly (and how many of them does the language provide? I can never remember). 使用caddr方法更好,但仅使用少量方法(该语言提供了多少?我不记得了)。 Still better, if your data is conceptually a list, is to use functions with names like first & second because they say what you actually mean (if your data is conceptually a tree of conses, then car &c are better probably). 更好的是,如果您的数据从概念上讲是一个列表,则应使用具有诸如firstsecond类的名称的函数,因为它们表明您的实际含义 (如果从概念上讲,您的数据是一棵简陋的树,那么car &c可能更好)。 But they still have the 'how many of them are there this week' problem. 但是他们仍然有“本周有多少人”的问题。

The right solution is to use destructuring &/or pattern matching to bind variables according to the shape of your data. 正确的解决方案是使用解构和/或模式匹配根据数据的形状绑定变量。 This makes your code actually clear. 这实际上使您的代码清晰。 Racket has a comprehensive mechanism for this, which I don't really understand in detail, but I know enough to get me through. Racket为此提供了一个全面的机制,虽然我并不十分详细地了解它,但是我知道足以让我顺利通过。 Here is (a fixed) version of your function which uses match to do the work: 这是您的函数的(固定)版本,使用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")]))

(note this could do with better variable names: I don't know what the various bits of the structure mean). (请注意,这可以使用更好的变量名:我不知道结构的各个位的含义)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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