2017-04-11 207 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)