Схема: посоветовать по внедрению сглаживать
Моя реализация flatten
выглядит так:
(define flatten
(lambda (lst)
(if (null? lst)
lst
(append
(rtn-lst (car lst))
(flatten (cdr lst))))))
(define rtn-lst
(lambda (lst)
(cond
((null? lst)
empty)
((atom? lst)
(list lst))
(else
(flatten lst)))))
Хотя стандартная реализация это:
(define (flatten lst)
(cond
((null? list)
empty)
((list? (car lst))
(append (flatten (car lst)) (flatten (cdr lst))))
(else
(cons (car lst) (flatten (cdr lst))))))
Помимо очевидной многословности, что еще не так с моим кодом?
3 ответа
Решение
Я бы попробовал это:
(define rtn-lst
(lambda (lst)
(cond
((list? lst)
(if (null? lst)
empty
(flatten-list lst)))
((atom? lst)
(list lst))
(else
(flatten-list lst)))))
Вероятно, у нас есть разные реализации Схемы.
РЕДАКТИРОВАТЬ:
С измененным else
ветка:
(define rtn-lst
(lambda (lst)
(cond
((list? lst)
(if (null? lst)
empty
(flatten-list lst)))
(else
(list lst)))))
Я бы посчитал atom?
ошибаться. Вы хотите знать, если lst
это список, так что используйте list?
, atom?
может вернуть ложь на vector
или же string
для некоторых реализаций. Но я не знаю точно. Все остальное хорошо.
Как насчет чего-то вроде этого:
(define foo
(lambda (e)
(cond ((pair? e) `(,@(foo (car e)) ,@(foo (cdr e))))
((null? e) '())
(else (list e)))))
Где например:
> (foo '(((2 3) (4 . 5) 8)))
(2 3 4 5 8)
Делает ли это то, что вы хотите?
Как насчет чего-то вроде этого:
(define (flatten x y)
(if (null? x)
y
(if (list? (car x))
(flatten (append (car x) (cdr x)) y)
(flatten (cdr x) (append y (list (car x)))))))
(define (flat x)
(flatten x '()))
> (flat '(1(2(3(4(5)6)7)8)9))
(1 2 3 4 5 6 7 8 9)
и версия закрытия:
(define (flatten x)
(define (flatten x y)
(if (null? x)
y
(if (list? (car x))
(flatten (append (car x) (cdr x)) y)
(flatten (cdr x) (append y (list (car x)))))))
(flatten x '()))
> (flatten '(1(2(3(4(5)6)7)8)9))
(1 2 3 4 5 6 7 8 9)