我想寫一個代碼,從列表的每個頂級元素中刪除括號。例如,輸入'((1 2)(3 4))將產生'(1 2 3 4),而輸入'((x(y))z'應產生'(x(y)z)。刪除球拍列表中的括號
有沒有辦法識別括號對?我想我可以找到一對括號並將其刪除,但我不知道如何做到這一點,以及如何從頂部元素中刪除。
我想寫一個代碼,從列表的每個頂級元素中刪除括號。例如,輸入'((1 2)(3 4))將產生'(1 2 3 4),而輸入'((x(y))z'應產生'(x(y)z)。刪除球拍列表中的括號
有沒有辦法識別括號對?我想我可以找到一對括號並將其刪除,但我不知道如何做到這一點,以及如何從頂部元素中刪除。
模式「我正在嘗試(做某事)列表的每個頂級元素」是一個肯定的跡象,map
將涉及。此外,一個大線索是在你的第一個例子情況:
'((1 2) (3 4)) => '(1 2 3 4)
這只是append*
!
(append* '((1 2) (3 4))) => '(1 2 3 4)
但是,這不是'((x (y)) z) => '(x (y) z)
的情況。
(append* '((x (y)) z)) => '(x (y) . z)
如果你想想看,append*
是非常接近你想要什麼:它解開從列表中的每個元素的括號中的一個級別。問題是,你輸入的一些元素不是列表,所以沒有什麼可以解開的。
我們可以通過將每個非列表元素包裝在單例列表中來解決此問題,以便'((x (y)) z)
變爲'((x (y)) (z))
。然後我們可以使用append*
:
(append* '((x (y)) (z))) => '(x (y) z)
這是map
來得心應手。 map
是一個函數,它使用函數(f
)和列表(lst
),並返回通過將f
應用於lst
的每個元素而生成的新列表。例如:
(map symbol? '(a 2 b c 5)) => '(#t #f #t #t #f)
假設你寫了一個函數,它接受一個參數,或者返回它不變,如果它是一個列表或者包裝起來作爲一個單列表,如果它不是。我們稱之爲maybe-wrap
。然後,你可以在你輸入映射maybe-wrap
,其結果可能被傳遞給append*
:
(define (remove-parens lst)
(append* (map maybe-wrap lst)))
我要把它留給你寫maybe-wrap
。
不幸的是,我對於Racket真的很陌生,而且從未與地圖合作過。但從你說的話看來,我可以用append替換「some-function」? – Vic
@Vic不完全。我已經更新了我的答案。看看現在是否有幫助。 –
不使用append
或map
,你可以定義mutually recursive功能做你想做的,如下:
(define (unwrap lst)
(if (null? lst)
'()
(my-append (car lst) (cdr lst))))
(define (my-append lhs rhs)
(cond
[(null? lhs)
(unwrap rhs)]
[(pair? lhs)
(cons (car lhs)
(my-append (cdr lhs) rhs))]
[else
(cons lhs (unwrap rhs))]))
例如:
> (unwrap '((1 2) (3 4 (5 (6)))))
'(1 2 3 4 (5 (6)))
> (unwrap '((x (y)) z))
'(x (y) z)
是您輸入一個字符串,或S-表達? –
輸入是一個列表! – Vic