Устранить внутреннюю скобку приводит к пустому списку и не исключает использование минусов - PullRequest
1 голос
/ 13 февраля 2012

Цель состоит в том, чтобы устранить все внутренние скобки.

(сгладить (a (bc) d)) становится '(abcd)

Это мой код в 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: ()

, что означает, что я пытаюсь получить доступ к car и cdr из пустого списка.

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)

Как предположил Росс Ларсон, append заставит программу работать.Но ради изучения, если у кого-то есть время, чтобы сэкономить, результаты моих тестов показывают только пройденные базовые случаи (2-й и пустой список)

Я думал о написании функции-оболочки, которая вызывает (cons (flatten slist) empty)

Ответы [ 2 ]

5 голосов
/ 13 февраля 2012

Проблема заключается в следующем выражении:

((сглаживать (автомобильная рама)) ...)

Это означает, применять все, что угодно (сглаживать ...)возвращается.Но так как это возвращает список, приложение завершается ошибкой.

Измените его на

(flatten (car slist))

1 голос
/ 14 февраля 2012

минусы воссоздадут структуру (как вы заметили).Вместо этого взгляните на приложение.

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

(другие проблемы, как мне кажется, не рассматриваютсядругие ответы зафиксировали применение значения рекурсии)

...