[英]Scheme: Return all elements of an expression that can be obtained using any combination of car and cdr
我正在嘗試在CS類的Scheme(R5RS)中編寫一個過程,該過程將一個表達式(符號或列表)作為參數並返回(1)的所有可能表達式的列表,這些表達式可以通過使用car和cdr代表表達式(2)和一個表達式,說明如何獲得原始表達式的這些組成部分。 如果可以通過多種方式獲得一件作品,則應將其退回不止一次。
Examples
(pieces '()) => ((() x))
(pieces 'apple) => ((apple x))
(pieces '(apple)) => (((apple) x) (apple (car x)) (() (cdr x)))
(pieces '(a (b c))) =>
(((a (b c)) x)
(a (car x))
(((b c)) (cdr x))
((b c) (car (cdr x)))
(b (car (car (cdr x))))
((c) (cdr (car (cdr x))))
(c (car (cdr (car (cdr x)))))
(() (cdr (cdr (car (cdr x)))))
(() (cdr (cdr x))))
由於我們剛剛開始使用Scheme,因此僅限於此分配的相當基本的語法。 這是我到目前為止的內容:
(define pieces
(lambda (exp)
(cond
((symbol? exp)
(list exp 'x))
((null? exp)
(list '() 'x))
((list? exp)
(let ((b (pieces (car exp))) (c (pieces (cdr exp))))
(list exp 'x b c))))))
(pieces '()) => (() x)
(pieces 'apple) => (apple x)
(pieces '(apple)) => ((apple) x (apple x) (() x))
(pieces '(a (b c))) => ((a (b c)) x (a x) (((b c)) x ((b c) x (b x) ((c) x (c x) (() x)))
(() x)))
該過程返回所有適當的元素,但是每次遞歸都會使這些組件嵌套在其他列表中。 有什么辦法可以防止這種情況?
另外,我不知道問題的第二部分從哪里開始(顯示如何使用car和cdr從原始元素中獲取每個元素)。 我已經嘗試了上百萬種不同的方法,但是沒有一個方法接近於可行。 如果有人對如何實現該功能有任何提示或建議,我將非常感謝。 萬分感謝。
(pieces 'apple) => (apple x)
但這應該是((apple x))
,對嗎? 您應該得到一個列表,其中第一個也是唯一的元素是列表(apple x)
。
終止遞歸的cond子句(exp是符號或null)將返回應包含在列表中的項目,而在car
和cdr
上遞歸的子句則嘗試創建項目列表。 由於pieces
既可以返回項目又可以返回項目列表,因此很難根據從其返回的值中列出項目:當您這樣做(list exp 'xbc)
您不知道b
和c
是否為項目應該進入一個或多個項目列表。
如果您確保pieces
始終返回項列表(例如(list (list exp 'x))
),則變得容易得多。 當您再次使用car
和cdr
您想要執行類似append
列表a
和b
然后將“當前”( (list exp 'x)
)項添加到該列表中(可能包含cons
或其他內容)。
對於第二部分, pieces
必須知道如何到達當前項目。 您可以使pieces
采用到當前項目的“路徑”作為(可能是可選的)參數。 如果路徑是一個列表,那么當你調用pieces
上(car exp)
你可以添加一個car
象征你發送作為參數的路徑,以及(cdr exp)
可以添加符號cdr
。 然后,使用該路徑創建一些不錯的東西來代替'x
in (list exp 'x)
。
我知道這不是Scheme,但也許看看類似的語言會有所幫助。 我做了更多這樣的練習來練習自己,所以滴一滴鹽就可以了,但它似乎完全可以滿足您的要求:
(defun parse-list (whatever)
(labels ((pieces (expression &optional path)
(cond
((null expression)
`((,path . nil)))
((listp expression)
(append (list
`(,path . ,expression))
(pieces (car expression)
(cons 'car path))
(pieces (cdr expression)
(cons 'cdr path))))
(t `((,path . ,expression))))))
(dolist (output (pieces whatever))
(format t "path ~a => result ~a~&"
(car output) (cdr output)))))
(parse-list '(a (b c)))
然后產生以下輸出:
path NIL => result (A (B C))
path (CAR) => result A
path (CDR) => result ((B C))
path (CAR CDR) => result (B C)
path (CAR CAR CDR) => result B
path (CDR CAR CDR) => result (C)
path (CAR CDR CAR CDR) => result C
path (CDR CDR CAR CDR) => result NIL
path (CDR CDR) => result NIL
抱歉,我無法獲得比這更好的SO的代碼格式:)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.