I am working my first project in scheme and have come across an issue. In part of my requirements, I am required to append all top-level sublists (eg '((1 2)(3 4 (5 6))) -> (1 2 3 4 (5 6)) and '((1 2 3)(4 5)) -> (1 2 3 4 5)
I've managed to get it working down to a single list, but this flattens all levels:
(cond
((null? lst)
lst)
((list? lst)
(append2(append-subs(car lst))(append-subs(cdr lst))))
(else
(cons lst '())))
Variations of this (eg. (else lst)
run the error "object 6, passed as first arg to cdr, is not correct type"
. Another method I attempted is as follows:
(cond
((null? lst)
lst)
((>= (len (cdr lst)) 0)
(append2(append-subs(car (list lst)))(append-subs(cdr (list lst)))))
(else
lst)
Which infinitely loops. I'm at a bit of a stand still, so any help would be greatly appreciated. (Note: Use of functions other than those used here is forbidden. Limited to list, list?, if, cond, null? ...)
Your list '(e1 e2 e3)
would be like this:
(cons e1 (cons e2 (cons e3 '())))
or if you like dotted notation:
'(e1 . (e2 . (e3 . ())))
Where en
is eiter #f
or #t
for (list? en)
Your assignment is to cons en
onto the recursion with the same level while with a list you need to append the two.
Here is a general idea how to implement it with level as an input parameter:
;;; flatten a list a certain levels
;;; level of zero is identity
(define (flatten-level level lst)
(cond ((or (zero? level)
(null? lst))
lst)
;; pair? is faster but will fall through for dotted
((list? (car lst))
(append (flatten-level <??> <??>)
(flatten-level <??> <??>)))
(else
(cons <??>
(flatten-level <??> <??>)))))
(flatten-level 0 '((1 2)(3 (((4 . 3))) (5 (6))) . 7))
; ==> ((1 2) (3 (((4 . 3))) (5 (6))) . 7) (aka identity)
(flatten-level 1 '((1 2)(3 (((4 . 3))) (5 (6))) . 7))
; ==> (1 2 3 (((4 . 3))) (5 (6)) . 7)
(flatten-level 99 '((1 2)(3 (((4 . 3))) (5 (6))) . 7))
; ==> (1 2 3 (4 . 3) 5 6 . 7)
How about appending all elements of the top list:
(define (flatten-top-level lst)
(apply append lst))
Which is practically the definition of append*
If '(a (b) (cf))
is a valid input, (first element not a list) then you can try:
(define (flatten-top-level lst)
(apply append
(map (lambda (e) (if (list? e)
e
(list e))) ;make a list from the non-list element
lst)))
2nd option: Fold it!
(define (flatten-top-level lst)
(foldr append '() lst))
For a list (abcd) where a, b, c, d are sub-lists; it is equal to:
(append a (append b (append c (append d '()))))
Extra : this is tail recurssive and therefore runs in linear time :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.