2017-04-11 204 views
1

我想寫一個代碼,從列表的每個頂級元素中刪除括號。例如,輸入'((1 2)(3 4))將產生'(1 2 3 4),而輸入'((x(y))z'應產生'(x(y)z)。刪除球拍列表中的括號

有沒有辦法識別括號對?我想我可以找到一對括號並將其刪除,但我不知道如何做到這一點,以及如何從頂部元素中刪除。

+0

是您輸入一個字符串,或S-表達? –

+0

輸入是一個列表! – Vic

回答

0

模式「我正在嘗試(做某事)列表的每個頂級元素」是一個肯定的跡象,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

+0

不幸的是,我對於Racket真的很陌生,而且從未與地圖合作過。但從你說的話看來,我可以用append替換「some-function」? – Vic

+0

@Vic不完全。我已經更新了我的答案。看看現在是否有幫助。 –

0

不使用appendmap,你可以定義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)