"任意precision单位及QUOT的倍增;方案 [英] "Multiplication of Arbitrary Precision Numbers" in Scheme

查看:226
本文介绍了"任意precision单位及QUOT的倍增;方案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是code到,我一直在努力了几天的一个问题。我遇到的问题是,由于某种原因,当我打电话:

 (APA-多(7 3 1 2)'(6 1 4))

返回的是:

 '(4 8 9 5 6 8)

答案,它应该输出

 (4 4 8 9 5 6 8)

当我打电话:

 (APA-多(3 1 2)'(6 1 4))

输出是:

 (1 9 1 5 6 8)

这是正确的。

我已经调试我的code多次,我似乎无法找出是什么问题(顺便说一句,我知道,我写了删除空的功能是最有可能的不必要的) 。 谁能告诉我在哪里,我错了吗?(我对这个问题的目标是保持任意precision号码列表格式,我不能创建一个从列表转换数的函数 - > NUM或num->列表)我相信,我已经提供了所有必要的code有人来上班了什么,我要去了,但如果不是,请让我知道。我有这个提示是,通过E D = DNDN-1 ... D1的乘法= EMEM-1 ... E1可以通过规则德= D * E1 + 10 *(D * EM进行EM-1 ... E2))。

 (定义(删除空L)
 (定义(删除空-H L ACCUM)
   (条件((空?L)ACCUM)
      ((空?(车长))
      (删除空(CDR L)))
      (否则(缺点(车长)(删除空-H(CDR L)ACCUM)))))
 (删除空-H L'()))(定义(APA-添加LST1 LST2)
 (定义(APA-添加-H LST1 LST2进位)
  (条件((和(空?LST1)(空?LST2))
             (如果(未(= 0进位))
                 (单进位)
                 '()))
       ((空?LST1)(附加(APA-添加-H LST1'()进行)
                              (列表(+(车(反向-L LST2))携带))
                              (反向-L(CDR(反向-L LST2)))))
       ((空?LST2)(附加(APA-添加-H'()LST2进位)
                              (列表(+(车(反向-L LST1))携带)))
                              (反向-L(CDR(反向-L LST1))))
       (其他
          (追加(APA-添加-H(CDR LST1)(CDR LST2)(商数(+(车LST1)(汽车LST2)携带)10))
                 (名单(模(+(车LST1)(汽车LST2)携带)10))))))
   (APA-附加小时(反向-L LST1)(反向-L LST2)0))(定义(D-乘LST因子)
  (定义(D-乘-H LST因素进位)
    (条件((空?LST)(如果(= 0随身携带)
                        '()
                        (单进位)))
       ((> =(+(*(汽车LST)的因素)进行)10)
        (追加;(列表(查看空自运-MULT LST进位))
                 (D-乘-H(CDR LST)因子(商(+(*(汽车LST)的因素)进行),10))
                 (名单(模(+(*(汽车LST)的因素)进行),10))))       (其他(附加;(列表(查看空自运-MULT LST进位))
                      (D-乘-H(CDR LST)因子(商(+(*(汽车LST)的因素)进行),10))
                      (列表(+(*(汽车LST)的因素)开展))))))
  (删除空(D-乘-H(反向-L LST)的因素0)))   (定义(nlength升)
     (如果(空?升)
       0
       (+ 1(nlength(CDR 1)))))
(定义(APA-多D E)
 (定义温度'())
  (条件((=(MAX(nlength E)(nlength D))(nlength E))
      (设定!温度E)
      (设定!E D)
      (设定!D组温度))
     (其他
      (设定!温度D)
      (设定!D E)
      (设定E!TEMP)))(定义(APA-多H D E)
  (条件((空?E)(列表0))
       (其他(附加(APA-ADD(D-乘D(车e))
                       (追加(APA-多H D(CDR E))(列表0)))))))
 (APA-多H D(反L E)))


解决方案

不知道为什么它不工作,所有这些附加和挫折是难以遵循,而且不知道是怎么回事了所有那一套!东东。把国家变成一个尾调用是一个更容易跟踪和通常更有效的引导。

 (定义(APA-ADD。列表)
      (定义(CDR的 - 没有空L)
                   (条件((空?L)'())
                         ((空?(CDAR 1))(的CDR-没有空(CDR L)))
                         (其他(利弊(CDAR升)(的CDR-没有空(CDR 1))))))
        (让循环((进0)(列表(图反向列表))(总和'()))
              (如果(空?列表)
                  (如果(零?携带)和(利弊进行总和))
                  (环(商数(折+进位(图车列表))10)
                        (CDR的 - 无空列表)
                        (缺点(模(折+进位(图车列表))10)之和)))))       (定义(APA-MULT。列表)
            (定义(多重按系数n阶L)
              (让循环((订货订单)(L(反L))(携带0)(总和'()))
                (条件((大于0阶)(环路( - 1阶)l进位(0利弊之和)))
                      ((空?L)(如果(零?随身携带)
                                     和
                                     这里(利弊进行总和)));;如果错误进行> 9
                      (否则(环路0
                                  (CDR L)
                                  (商(+进位(* N(车长)))10)
                                  (利弊(模(+进位(* n个(轿厢L)))10)之和))))))
             (定义(APA-mult2 L1 L2)
               (让((RL1(反向L1))
                     (RL2(反向L2))
                     (拉链带阶
                        (拉姆达(L)
                          (让循环((0阶)(L L)(ACCUM'()))
                             (如果(空?L)的
                                 ACCUM
                                 (环路(+ 1阶)
                                       (CDR L)
                                       (缺点(缺点(车长)顺序)ACCUM)))))))
                   (折叠APA-ADD(0)(图(拉姆达(X)
                                              (多重逐因子(汽车x)的(CDR x)的L2))
                                           (拉链带阶RL1)))))
            (折叠APA-mult2(1)列表)))

(APA-MULT'(3 1 2)'(6 1 4)))

值7:(1 9 1 5 6 8)

(APA-MULT'(2 0 0)(3 1 2)'(6 1 4))

值8:(3 8 3 1 3 6 0 0)

(APA-MULT'(7 3 1 2)'(6 1 4))

值9:(4 4 8 9 5 6 8)

The following is code to a problem that I have been working on for a few days. The problem I encountered is that for some reason when I call:

(apa-multi '(7 3 1 2) '(6 1 4))

the return is:

'(4 8 9 5 6 8)

The answer that it should output is

'(4 4 8 9 5 6 8)

When I call:

(apa-multi '(3 1 2) '(6 1 4))

The output is:

 '(1 9 1 5 6 8)

which is correct.

I have debugged my code multiple times, and I can't seem to find out what the problem is (by the way, I know that the "remove-empty" function that I wrote is most likely unnecessary). Can anyone tell me where I am going wrong here? (My goal for this problem is to keep the arbitrary precision numbers in list format, and I can not create a function that converts numbers from list->num or num->list.) I believe that I have provided all of the necessary code for someone to work out what I was going for, but if not please let me know. The hint that I have for this is that " Multiplication of d = dndn−1 ...d1 by e = emem−1 ...e1 can be carried out by the rule de=d∗e1 +10∗(d∗em em−1...e2).)"

(define (remove-empty L)
 (define (remove-empty-h L accum)
   (cond ((null? L) accum)
      ((null? (car L)) 
      (remove-empty (cdr L)))
      (else (cons (car L) (remove-empty-h (cdr L) accum)))))
 (remove-empty-h L '()))

(define (apa-add lst1 lst2)
 (define (apa-add-h lst1 lst2 carry)
  (cond ((and (null? lst1) (null? lst2)) 
             (if (not (= 0 carry)) 
                 (list carry)
                 '()))
       ((null? lst1)  (append (apa-add-h lst1 '() carry)
                              (list (+ (car (reverse-l lst2)) carry))
                              (reverse-l(cdr (reverse-l lst2)))))
       ((null? lst2)  (append (apa-add-h '() lst2 carry)
                              (list (+ (car (reverse-l lst1)) carry)))
                              (reverse-l(cdr (reverse-l lst1))))
       (else 
          (append (apa-add-h (cdr lst1) (cdr lst2) (quotient (+ (car lst1) (car lst2) carry) 10)) 
                 (list (modulo (+ (car lst1) (car lst2) carry) 10))))))
   (apa-add-h (reverse-l lst1) (reverse-l lst2) 0))

(define (d-multiply lst factor)
  (define (d-multiply-h lst factor carry)
    (cond ((null? lst) (if (= carry 0)
                        '()
                        (list carry)))
       ((>= (+ (* (car lst) factor) carry) 10)
        (append  ;(list (check-null-and-carry-mult lst carry))
                 (d-multiply-h (cdr lst) factor (quotient (+ (* (car lst) factor) carry) 10))
                 (list (modulo (+ (* (car lst) factor) carry) 10))))         

       (else (append   ;(list (check-null-and-carry-mult lst carry))
                      (d-multiply-h (cdr lst) factor (quotient(+ (* (car lst) factor) carry) 10))
                      (list (+ (* (car lst) factor) carry))))))
  (remove-empty (d-multiply-h (reverse-l lst) factor 0)))

   (define (nlength l)
     (if (null? l)
       0
       (+ 1 (nlength (cdr l)))))


(define (apa-multi d e)
 (define temp '())
  (cond ((= (max (nlength e) (nlength d)) (nlength e))
      (set! temp e)
      (set! e d)
      (set! d temp))
     (else
      (set! temp d)
      (set! d e)
      (set! e temp)))

(define (apa-multi-h d e)
  (cond ((null? e) (list 0))
       (else (append  (apa-add (d-multiply d (car e)) 
                       (append (apa-multi-h d (cdr e)) (list 0)))))))
 (apa-multi-h d (reverse-l e)))

解决方案

Not sure why it doesn't work, all those appends and reverses are hard to follow, and not sure what's going on with all that set! stuff. Putting the state into a tail call is a lot easier to follow and usually more efficient to boot.

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



       (define (apa-mult . Lists)
            (define (mult-by-factor n order L)
              (let loop ((order order) (L (reverse L)) (carry 0) (sum '()))
                (cond ((> order 0) (loop (- order 1) L carry (cons 0 sum)))
                      ((null? L) (if (zero? carry) 
                                     sum 
                                     (cons carry sum))) ;;bug here if carry > 9
                      (else (loop 0 
                                  (cdr L) 
                                  (quotient (+ carry (* n (car L))) 10) 
                                  (cons (modulo (+ carry (* n (car L))) 10) sum))))))
             (define (apa-mult2 L1 L2)
               (let ((rL1 (reverse L1))
                     (rL2 (reverse L2))
                     (zip-with-order
                        (lambda (L) 
                          (let loop ((order 0) (L L) (accum '()))
                             (if (null? L) 
                                 accum
                                 (loop (+ 1 order) 
                                       (cdr L)  
                                       (cons (cons (car L) order) accum)))))))
                   (fold apa-add '(0) (map (lambda (x) 
                                              (mult-by-factor (car x) (cdr x) L2))
                                           (zip-with-order rl1)))))
            (fold apa-mult2 '(1) Lists)))

(apa-mult '(3 1 2) '(6 1 4)))

;Value 7: (1 9 1 5 6 8)

(apa-mult '(2 0 0) '(3 1 2) '(6 1 4))

;Value 8: (3 8 3 1 3 6 0 0)

(apa-mult '(7 3 1 2) '(6 1 4))

;Value 9: (4 4 8 9 5 6 8)

这篇关于"任意precision单位及QUOT的倍增;方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆