簡體   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