Recursion 使用数字列表的任意精度加法

Recursion 使用数字列表的任意精度加法,recursion,scheme,racket,addition,arbitrary-precision,Recursion,Scheme,Racket,Addition,Arbitrary Precision,我想做的是把两个列表相加,就像每个列表是一个整数一样 (定义(反向lst) (如果(空?lst) '() (附加(反向(cdr lst)) (列表(车辆lst(()))) (定义(apa添加l1和l2) (定义(apa添加帮助l1 l2) (cond((和(null?l1)(null?l2))'()) ((null?l1)(列表(+(apa添加帮助’()(cdr l2()()))) ((null?l2)(列表(+(apa添加帮助(cdr l1))(俎俎俎) ((>=(+(l1车厢)(l2车厢))

我想做的是把两个列表相加,就像每个列表是一个整数一样

(定义(反向lst)
(如果(空?lst)
'()
(附加(反向(cdr lst))
(列表(车辆lst(())))
(定义(apa添加l1和l2)
(定义(apa添加帮助l1 l2)
(cond((和(null?l1)(null?l2))'())
((null?l1)(列表(+(apa添加帮助’()(cdr l2()())))
((null?l2)(列表(+(apa添加帮助(cdr l1))(俎俎俎)
((>=(+(l1车厢)(l2车厢))10)
(附加(apa添加帮助(cdr l1)(cdr l2))
(列表(商(+(l1车)(l2车))10)
(列表(模(+(汽车l1)(汽车l2))10));这是一个问题
(其他(附加(apa添加帮助(cdr l1)(cdr l2))
(列表(+(l1车)(l2车(()())))
(apa添加帮助(反向l1)(反向l2)))
(行政程序增订"4 7 9"(7 8 4)
>'(1 1 1 5 1 3)

我知道问题是围绕我的递归展开的,我颠倒了列表的顺序以便于处理,但是我似乎不知道如何将我的模值(结转值)添加到列表中的下一个对象。我怎样才能做到这一点呢?

反向
已经在Racket中定义,所以不需要重新定义它

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

比如

-> (apa-add '(4 7 9) '(7 8 4))
'(1 2 6 3)
-> (+ 479 784)
1263
car0
cdr0
是帮助我继续将空列表作为零列表处理的函数

我引入了一个新变量carry,它用于将值从一个迭代带到另一个迭代,就像手动操作一样

编辑1

名为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)))

我对你的代码有点困惑,循环函数到底是什么?并携带0?请参阅我对命名let的编辑。“进位”是10以上的值,该值被带到下一个加法中,除以10。
res
apa add helper
过程的结果。当什么都不做时(列表为空,进位=0),则返回
res
作为结果。在
apaaddhelper
末尾的递归调用中,新计算的数字(dn)将在
res
前面加上
cons
。这使得递归的apa add helper可以是尾部递归的。为什么我们不能使用racket提供给我们的内置car和cdr?如果您使用内置car和cdr功能,您需要检查此功能中的更多条件。“car0”检查列表是否为空,如果不是空,则取其中的car,否则返回0。将0添加到某个对象不会更改其值,这就是此代码按预期工作的原因。
(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)))