[英]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
有兩個單元格。 car
和cdr
。 單元格可以顯示為(a . b)
,其中a
和b
可以是任何值。
一對有另一種表示形式。 如果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.