"任意precision单位及QUOT的倍增;方案 [英] "Multiplication of Arbitrary Precision Numbers" in Scheme
问题描述
以下是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屋!