Scheme中的“添加任意精度数”

时间:2013-10-23 17:24:42

标签: recursion scheme precision addition

我试图在保留列表格式的同时在方案中添加两个数字(从列表中)。但是,当用于计算的数字增加到大于或等于10的值时,我会得到不希望的结果。例如:

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

(define (apa-add lst1 lst2)
  (cond ((null? lst1) lst2)
    ((null? lst2) lst1)
    ((>= (+ (car lst1) (car lst2)) 10) 
     (append (apa-add (cdr lst1) (cdr lst2)) 
         (list (quotient(+ (car lst1) (car lst2)) 10)) 
         (list (modulo (+ (car lst1) (car lst2)) 10))))
        (else 
         (append (apa-add (cdr lst1) (cdr lst2))
         (list (+ (car lst1) (car lst2)))))))

(apa-add (reverse '(4 4 5)) (reverse'(3 5 8)))

返回

'(7 9 1 3)

如何修改代码以修复此错误?我想使用let语句,因此我可以将(quotient (+ (car lst1) (car lst2)) 10)的评估添加到下一个调用的(list (+ (car lst1) (car lst2))),但我想不出如何执行此操作。

1 个答案:

答案 0 :(得分:1)

使这成为一个尾调用简化了一些事情。

(define (apa-add lst1 lst2)
  (let loop ((carry 0) (L1 (reverse lst1)) (L2 (reverse lst2)) (sum '()))
     (cond ((and (null? l1) (null? l2)) 
            (if (zero? carry) sum (cons carry sum)))
           ((null? L1) 
            (loop (quotient (+ carry (car l2)) 10)
                  '() 
                  (cdr L2) 
                  (cons (modulo (+ carry (car l2)) 10) sum)))
           ((null? L2) 
            (loop (quotient (+ carry (car l1)) 10)
                  (cdr l1) 
                  '() 
                  (cons (modulo (+ carry (car l1)) 10) sum)))
           (else  
            (loop (quotient (+ carry (car l1) (car l2)) 10)
                  (cdr l1) 
                  (cdr l2)
                  (cons (modulo (+ carry (car l1) (car l2)) 10) sum))))))              



(apa-add (list 4 4 5) (list 3 5 8))

;Value 4: (8 0 3)

可能不会太难转换为n-arity函数。

(define (apa-add . Lists)
  (define (cdrs-no-null L)
               (cond ((null? L) '())
                     ((null? (cdar l)) (cdrs-no-null (cdr L)))
                     (else (cons (cdar l) (cdrs-no-null (cdr l))))))
    (let loop ((carry 0) (Lists (map reverse Lists)) (sum '()))
          (if (null? Lists)
              (if (zero? carry) sum (cons carry sum))
              (loop (quotient (fold + carry (map car Lists)) 10)
                    (cdrs-no-null Lists)
                    (cons (modulo  (fold + carry (map car Lists)) 10) sum)))))

(apa-add (list 4 4 5) (list 3 5 8) (list 1 0 2 7))

;Value 11: (1 8 3 0)

(apa-add (list 4 4 5) (list 3 5 8))

;Value 12: (8 0 3)