How to Reverse a List?

前端 未结 7 2183
有刺的猬
有刺的猬 2020-12-03 06:28

What is the function to a list in Scheme? It needs to be able to handle nested lists.

So that if you do something like (reverse \'(a (b c d) e)) you\'ll

7条回答
  •  天命终不由人
    2020-12-03 06:43

    (define (my-reverse ls)
      (define (my-reverse-2 ls acc)
        (if (null? ls)
          acc
          (my-reverse-2 (cdr ls) (cons (car ls) acc))))
      (my-reverse-2 ls '()))
    

    This uses an accumulator variable to reverse the list, taking the first element off the incoming list and consing it to the front of the accumulator. It hides the accumulator taking function and just exposes the function that takes a list, so the caller doesn't have to pass in the empty list. That's why I have my-reverse-2.

    (my-reverse-2 '(a (b c d) e) '()); will call
    (my-reverse-2 '((b c d) e)  '(a)); which will call
    (my-reverse-2 '(e)  '((b c d) a)); which will call
    (my-reverse-2 '() '(e (b c d) a)); which will return
    '(e (b c d) a)
    

    Because the last function call in my-reverse-2 is a call to my-reverse-2, and the return value is passed right through (the return value of the first call is the return value of the second call, and so on) my-reverse-2 is tail optimized, which means it will not run out of room on the stack. So it is safe to call this with a list as long as you like.

    If you want it to apply to nested lists use something like this:

    (define (deep-reverse ls)
      (define (deep-reverse-2 ls acc)
        (if (null? ls)
            acc
            (if (list? (car ls))
                (deep-reverse-2 (cdr ls) (cons (deep-reverse (car ls)) acc))
                (deep-reverse-2 (cdr ls) (cons (car ls) acc)))))
      (deep-reverse-2 ls '()))
    

    This checks to see if the element is a list before adding it to the list, and if it is, reverses it first. Since it calls itself to revers the inner list, it can handle arbitrary nesting.

    (deep-reverse '(a (b c d) e)) -> '(e (d c b) a) which is in reverse alphabetical order, despite the fact that there is a nested list. It evaluates as so:

    (deep-reverse-2 '(a (b c d) e) '()); Which calls
    (deep-reverse-2 '((b c d) e)  '(a))
    (deep-reverse-2 '(e) (cons (deep-reverse-2 '(b c d) '()) '(a)))
    (deep-reverse-2 '(e) (cons (deep-reverse-2 '(c d)  '(b)) '(a)))
    (deep-reverse-2 '(e) (cons (deep-reverse-2 '(d)  '(c b)) '(a)))
    (deep-reverse-2 '(e) (cons '(d c b) '(a)))
    (deep-reverse-2 '(e)  '((d c b) a))
    (deep-reverse-2 '() '(e (d c b) a))
    '(e (d c b) a)
    

提交回复
热议问题