消除内括号进入空列表并且不消除使用缺点

时间:2012-02-13 14:56:21

标签: scheme racket flatten

目标是消除所有内部括号。

  

(展平'(a(b c)d))变为'(a b c d)

这是我在Racket中的代码

; if slist is null, return empty
; otherwise, if it is a pair, recursively solve car and cdr and concat them
; if it is a symbol, return the symbol

(define flatten
  (lambda (slist)
    (cond
      [ (null? slist) '()]
      [ (pair? slist)  
        (cons ((flatten (car slist)) (flatten (cdr slist))))]
      [ (symbol? slist) slist])))

抱怨

procedure application: expected procedure, given: c; arguments were: ()

表示我正在尝试访问空列表的carcdr

I did the trace:
> (flatten '(a (b c) d))
pair?-car-cdr
a
((b c) d)
symbol?
a
pair?-car-cdr
(b c)
(d)
pair?-car-cdr
b
(c)
symbol?
b
pair?-car-cdr
c
()
symbol?
c
(stops here)

跟踪代码很简单 - 一堆显示。

(define flatten
  (lambda (slist)
    (cond
      [ (null? slist) '()]
      [ (pair? slist) 
        (display 'pair?-car-cdr)
        (newline)
        (display (car slist))
        (newline)
        (display (cdr slist))
        (newline)
        (cons ((flatten (car slist)) (flatten (cdr slist))))]
      [ (symbol? slist) 
         (display 'symbol?)
         (newline)
         (display slist)
         (newline)
        slist])))

我不明白的是,第一个条件(null? slist)如何才能找到空列表?我有两个递归调用。如果它确实捕获了空列表,它将转到下一个递归,即列表{d}

我的递归逻辑有什么问题?


更新版本

(define flatten
  (lambda (slist)
    (cond
      [ (null? slist) '()]
      [ (pair? slist)  
        (cons (flatten (car slist)) (flatten (cdr slist)))]
      [ (symbol? slist) slist])))

(display (equal? (flatten '(a (b a) b a c (a b) c (e f (b a)))) '(a b a b a c a b c e f b a)))
(newline)
(display (equal? (flatten '(a b c)) '(a b c)))
(newline)
(display (equal? (flatten '(a (b c))) '(a b c)))
(newline)
(display (equal? (flatten '((a)(b)(c) d)) '(a b c d)))
(newline)
(display (equal? (flatten '(a (b) ((c)) (((d))) ((((e (f g))))))) '(a b c d e f g )))
(newline)
(display (equal? (flatten '()) '()))
(newline)
(display (equal? (flatten '(a b () ())) '(a b)))
(newline)

正如Ross Larson所说,追加将使该计划有效。但是为了学习,如果有人有空闲时间,我的测试结果只显示传递的基本情况(第二个和空列表)

我考虑过编写一个调用(cons (flatten slist) empty)

的包装函数

2 个答案:

答案 0 :(得分:5)

问题在于这个表达式:

  

((flatten(car slist))...)

这意味着,应用任何(展平...)返回。但既然如此 返回一个列表,应用程序失败。

将其更改为

  

(flatten(car slist))

答案 1 :(得分:1)

缺点是重建结构(如您所见)。请改为查看附加内容。

http://docs.racket-lang.org/reference/pairs.html

(我没有解决其他问题,因为似乎其他答案已经修复了递归值的应用)