arbitrary precision addition using lists of digits

后端 未结 1 1281
无人共我
无人共我 2020-12-22 05:11

What I\'m trying to do is take two lists and add them together like each list is a whole number.

(define (reverse          


        
相关标签:
1条回答
  • 2020-12-22 05:54

    reverse is already defined in Racket so there's no need to redefine it.

    I have rewritten your code for a version that is clearer (to me, at least):

    (define (apa-add l1 l2)
    
      (define (car0 lst) (if (empty? lst) 0 (car lst)))
      (define (cdr0 lst) (if (empty? lst) empty (cdr lst)))
    
      (let loop ((l1 (reverse l1)) (l2 (reverse l2)) (carry 0) (res '()))
        (if (and (null? l1) (null? l2) (= 0 carry)) 
            res
            (let* ((d1 (car0 l1))
                   (d2 (car0 l2))
                   (ad (+ d1 d2 carry))
                   (dn (modulo ad 10)))
              (loop (cdr0 l1) (cdr0 l2) (quotient (- ad dn) 10) (cons dn res))))))
    

    such as

    -> (apa-add '(4 7 9) '(7 8 4))
    '(1 2 6 3)
    -> (+ 479 784)
    1263
    

    car0and cdr0 are functions that help me to continue processing empty lists as a list of zeroes.

    I introduced a new variable, carry, which is used to carry a value from iteration to iteration, just as you do it manually.

    EDIT 1

    The named let is equivalent to the following code:

    (define (apa-add l1 l2)
    
      (define (car0 lst) (if (empty? lst) 0 (car lst)))
      (define (cdr0 lst) (if (empty? lst) empty (cdr lst)))
    
      (define (apa-add-helper l1 l2 carry res)
        (if (and (null? l1) (null? l2) (= 0 carry)) 
            res
            (let* ((d1 (car0 l1))
                   (d2 (car0 l2))
                   (ad (+ d1 d2 carry))
                   (dn (modulo ad 10)))
              (apa-add-helper (cdr0 l1) (cdr0 l2) (quotient (- ad dn) 10) (cons dn res)))))
    
      (apa-add-helper (reverse l1) (reverse l2) 0 '()))
    

    EDIT 2

    The non tail-recursive version would be

    (define (apa-add l1 l2)
    
      (define (car0 lst) (if (empty? lst) 0 (car lst)))
      (define (cdr0 lst) (if (empty? lst) empty (cdr lst)))     
    
      (define (apa-add-helper l1 l2 carry)
        (if (and (null? l1) (null? l2) (= 0 carry)) 
            '()
            (let* ((d1 (car0 l1))
                   (d2 (car0 l2))
                   (ad (+ d1 d2 carry))
                   (dn (modulo ad 10)))
              (cons dn (apa-add-helper (cdr0 l1) (cdr0 l2) (quotient (- ad dn) 10))))))
    
      (reverse (apa-add-helper (reverse l1) (reverse l2) 0)))
    
    0 讨论(0)
提交回复
热议问题