簡體   English   中英

反轉列表錯誤

[英]Reversing a list error

我正在學習DrRacket,並且需要編寫一個可以反轉列表的程序。 我有下面的內容,它正反轉數字,但是以某種方式將它們嵌套在列表或其他內容中。

(define (reverse-list lon)
  (if (empty? lon)
      empty
      (cons (reverse-list (rest lon))
            (cons (first lon)
                  empty))))

輸出(反向列表(列表1 2 3 4)):

(list (list (list (list empty 4) 3) 2) 1)

有人知道為什么輸出不只是一個列表嗎?

謝謝您的幫助!

cons有兩個單元格。 carcdr 單元格可以顯示為(a . b) ,其中ab可以是任何值。

一對有另一種表示形式。 如果b是另一對或空白列表,則可以替換. b ) . b )b不帶首字母(

(a . ())             ; ==> (a)
(a . (b . c))        ; ==> (a b . c)
(a . (b . (c . ()))) ; ==> (a b c)

現在為您的代碼。 想象一下,您嘗試使用(1 2 3 4) (或(1 . (2 . (3 . (4 . ()))))來進行嘗試。 使用替換規則,我們可以精確地計算您的程序執行的操作:

(reverse-list '(1 . (2 . (3 . (4 . ())))))                   ; ==>
(if (empty? '(1 . (2 . (3 . (4 . ())))))
    empty 
    (cons (reverse-list (rest '(1 . (2 . (3 . (4 . ()))))))
          (cons (first '(1 . (2 . (3 . (4 . ()))))) 
                empty)))                                      ; ==>
(if #f
    empty 
    (cons (reverse-list (rest '(1 . (2 . (3 . (4 . ()))))))
          (cons (first '(1 . (2 . (3 . (4 . ()))))) 
                empty)))                                      ; ==>

(cons (reverse-list '(2 . (3 . (4 . ()))))
      (cons 1 empty))                                      ; ==>

(cons (cons (reverse-list '(3 . (4 . ())))
            (cons 2 empty))
      (cons 1 empty))                                      ; ==>

(cons (cons (cons (reverse-list '(4 . ()))
                  (cons 3 empty))
            (cons 2 empty))
      (cons 1 empty))                                      ; ==>

(cons (cons (cons (cons (reverse-list '())
                        (cons 4 empty))
                  (cons 3 empty))
            (cons 2 empty))
      (cons 1 empty))                                      ; ==>

(cons (cons (cons (cons '()
                        (cons 4 empty))
                  (cons 3 empty))
            (cons 2 empty))
      (cons 1 empty))                                      ; ==>

((((() . (4 . ())) . (3 . ())) . (2 . ())) . (1 . ()))     ; ==>
((((() . (4)) . (3)) . (2)) . (1))                         ; ==>
((((() 4) 3) 2) 1)

現在。 真實的反向列表將以點分符號顯示如下:

(4 . (3 . (2 . (1 . ())))) ; ==> (4 3 2 1)

沒有其他辦法了。 您需要與cons非常親密,並了解如何顯示構造它們的不同方法。 提示是幾乎每個列表都是從頭到尾創建的,並從頭到尾進行迭代。

很高興看到您已經解決了自己的問題。 但是我覺得我應該選擇一點,因為反向列表確實可以按照您的方式建立一個迭代列表。

(define (reverse-list lon)
  ;; iterative helper procedure
  (define (aux lon acc)
    (if (empty? lon)
        acc
        (aux (rest lon) 
             (cons (first lon) acc))))
  ;; use helper
  (aux lon empty))

(reverse-list '(1 2 3 4)) ; ==> (4 3 2 1)

如您所見,我們從頭到尾進行迭代。 這樣做,到目前為止,我們將當前元素限制為累積列表,並且該操作是從頭到尾的。 Ei最后添加的元素將是結果中的第一個。 這樣做的好處是,我們為每個處理的單元格使用一個新單元格,它已成為最終結果的一部分。 每次使用append您都將復制第一個參數,以便n元素列表獲得(apply + (range n))不必要的單元分配。

經驗更豐富的Schemer將使用命名的let來執行本地過程並一次調用:

(define (reverse-list lon)
  (let aux ((lon lon) (acc empty))
    (if (empty? lon)
        acc
        (aux (rest lon) 
             (cons (first lon) acc)))))

因此,最終的工作是將第一個弊端替換為附加項以停止列表嵌套。

(define (reverse-list lon)
  (if (empty? lon) empty (append (reverse-list (rest lon)) (cons (first lon) empty))))

問題已解決,不過感謝您的幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM