reverse list - scheme

前端 未结 8 1918
清酒与你
清酒与你 2020-12-11 05:46

I\'m trying to reverse a list, here\'s my code:

(define (reverse list)
  (if (null? list) 
     list
      (list (reverse (cdr list)) (car list))))


        
相关标签:
8条回答
  • 2020-12-11 06:12

    The natural way to recur over a list is not the best way to solve this problem. Using append, as suggested in the accepted answer pointed by @lancery, is not a good idea either - and anyway if you're learning your way in Scheme it's best if you try to implement the solution yourself, I'll show you what to do, but first a tip - don't use list as a parameter name, that's a built-in procedure and you'd be overwriting it. Use other name, say, lst.

    It's simpler to reverse a list by means of a helper procedure that accumulates the result of consing each element at the head of the result, this will have the effect of reversing the list - incidentally, the helper procedure is tail-recursive. Here's the general idea, fill-in the blanks:

    (define (reverse lst)
      (<???> lst '()))                       ; call the helper procedure
    
    (define (reverse-aux lst acc)
      (if <???>                              ; if the list is empty
          <???>                              ; return the accumulator
          (reverse-aux <???>                 ; advance the recursion over the list
                       (cons <???> <???>)))) ; cons current element with accumulator
    

    Of course, in real-life you wouldn't implement reverse from scratch, there's a built-in procedure for that.

    0 讨论(0)
  • 2020-12-11 06:13

    Here's a solution using build-list procedure:

    (define reverse
      (lambda (l)
        (let ((len (length l)))
          (build-list len
                      (lambda (i)
                        (list-ref l (- len i 1)))))))
    
    0 讨论(0)
  • 2020-12-11 06:18

    Tail recursive approach using a named let:

    (define (reverse lst)
      (let loop ([lst lst] [lst-reversed '()])
        (if (empty? lst)
            lst-reversed
            (loop (rest lst) (cons (first lst) lst-reversed)))))
    

    This is basically the same approach as having a helper function with an accumulator argument as in Oscar's answer, where the loop binding after let makes the let into an inner function you can call.

    0 讨论(0)
  • 2020-12-11 06:18

    This one works but it is not a tail recursive procedure:

    (define (rev lst)
     (if (null? lst)
         '()
          (append (rev (cdr lst)) (car lst))))
    
    0 讨论(0)
  • 2020-12-11 06:20

    There's actually no need for appending or filling the body with a bunch of lambdas.

    (define (reverse items)
      (if (null? items)
          '()
          (cons (reverse (cdr items)) (car items))))
    
    0 讨论(0)
  • 2020-12-11 06:22

    I think it would be better to use append instead of cons

    (define (myrev l)
      (if (null? l)
          '()
          (append (myrev (cdr l)) (list (car l)))
      )
    )
    

    this another version with tail recursion

    (define (myrev2 l)
      (define (loop l acc) 
        (if (null? l)
            acc
            (loop (cdr l) (append (list (car l)) acc ))
        )
      )
      (loop l '())
    )
    
    0 讨论(0)
提交回复
热议问题