0

我想做的是取两个列表并将它们加在一起,就像每个列表都是一个整数一样。

(define (reverse lst)
 (if (null? lst)
  '()
  (append (reverse (cdr lst)) 
      (list (car lst)))))

(define (apa-add l1 l2)
  (define (apa-add-help l1 l2)
    (cond ((and (null? l1) (null? l2)) '())
      ((null? l1) (list (+ (apa-add-help '() (cdr l2)))))
      ((null? l2) (list (+ (apa-add-help (cdr l1) '()))))

      ((>= (+ (car l1) (car l2)) 10) 
       (append (apa-add-help (cdr l1) (cdr l2))               
               (list (quotient (+ (car l1) (car l2)) 10))
               (list (modulo (+ (car l1) (car l2)) 10)))) ;this is a problem

      (else (append (apa-add-help (cdr l1) (cdr l2))
                    (list (+ (car l1) (car l2)))))))

(apa-add-help (reverse l1) (reverse l2)))

(apa-add '(4 7 9) '(7 8 4))
>'(1 1 1 5 1 3)

我知道问题出在我的递归上,我颠倒了列表的顺序以使过程更容易,但是我似乎无法理解如何将模值(结转值)添加到列表中的下一个对象. 我怎样才能做到这一点?

4

1 回答 1

1

reverse已经在 Racket 中定义了,所以不需要重新定义它。

我已经为更清晰的版本重写了您的代码(至少对我而言):

(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))))))

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

car0并且cdr0是帮助我继续将空列表作为零列表处理的函数。

我引入了一个新变量,carry,它用于在迭代之间携带一个值,就像你手动做的一样。

编辑 1

named let等效于以下代码:

(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 '()))

编辑 2

非尾递归版本将是

(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)))
于 2013-10-25T18:27:46.020 回答