码迷,mamicode.com
首页 > 其他好文 > 详细

大整数乘法

时间:2015-05-02 20:47:02      阅读:319      评论:0      收藏:0      [点我收藏+]

标签:数学   算法   c++   大数乘法   

这算是分治的运用,在java中有个大数类,用着非常方便,但是在c/c++中就没有那么容易了,

一个整数最多也才2^64两个数字的加法或减法我们可以用数组模拟运算一遍,轻松搞定,但是两个数字的乘法呢,

比如给你这样两个数字:

A= 1234567898765432145673;

B=23456789463784628596936285;

现要求求出c=A*B, 好了问题来了怎么用算法实现呢,数组模拟运算效率太低了,一个n位和m位的数字相乘最少进行n*m次乘法运算,

在说如何运算前,我先说说如何减少乘法运算次数:

数学家高斯曾经说 (a1+b1*i)*(a2+b2*i)这样的两个复数,他可以用三次乘法运算计算出结果,

(a1+b1*i)*(a2+b2*i)=a1*b2 + (a1*b2 + b1*a2)*i - b1*b2 ,仔细一看这不是有4次乘法运算么,

其实他用了一个小优化,假设不是复数 (a1+b1)*(a2+b2) = a1*b2 + (a1*b2 + b1*a2)+ b1*b2 

那么 (a1*b2 + b1*a2) =  (a1+b1)*(a2+b2) - a1*b2 - b1*b2 ,

所以就可以(a1+b1*i)*(a2+b2*i) =  a1*b2 + ((a1+b1)*(a2+b2) - a1*b2 - b1*b2) *i -b1*b2 ;三次乘法,got;

说了这么多这对我们做大数的运算有什么作用呢:

是这样的对于两个大数相乘我们肯定是采用分治的方法

数字A= A1 * 10^(n/2) + A2;

       B=B1 * 10^(n/2) + B2; (当两个数字不一样长时在断的前面补0)

==>>  A*B = A1 * B1 * 10^n  +( A1* B2 + A2*B1 ) * 10^(n/2)  + A2*B2

分治的思想是:

   getans(A, B)

              if (  A.length   == 1  and   B.length == 1 )

                       return A*B;

              else

                       return getans(A1, B1)*10^n  + (getans(A1, B1)  +  getans(A1, B2) )*  10^(n/2) + getans(B1, B2);

看样子并不难的样子但是我么来算算时间复杂度,还是以乘法作为基本操作(以加法作为基本操作求出结果和乘法一样):

   O(1) = 1;

   O(n) = 4O(n/2);

   推到过程就不写了,但是最后算出来平均时间复杂度是O(n^2),和直接用数组模拟运算的复杂度是一样的,花这么大的力气写个66的代码并不6,

所以就优化,就用高斯的办法来优化,虽然加法次数增加了,但是最终结果是怎样的呢,推到一地啊就知道了:

换一个姿势后就有了:

    数字A= A1 * 10^(n/2) + A2;

           B=B1 * 10^(n/2) + B2; (当两个数字不一样长时在断的前面补0)

==>>  A*B = A1 * B1 * 10^n  +(  A*B  -  A1 * B1 * 10^n  - A2*B2 ) * 10^(n/2)  + A2*B2;

代码就变成下面的样子:

     getans(A, B)

              if (  A.length   == 1  and   B.length == 1 )

                         return A*B;

              else

                       X <— getans(A1, B1)*10^n  ;

                       Y <— getans(A2, B2) ;

                       return  X +  ( getans(A,B)  - X - Y )*10^(n/2)     + Y;

在来算时间复杂度就变成了:

        O(1) = 1;

        O(n) = 3*O(n/2);

最后平均时间复杂度就变成了O(n * log2,3 )了这不就小于O(n^2) 了,

(平均时间复杂度的推导过程涉及到数学变换,所以没有写,这一个递推式的求法很多书山也有讲) 

关于具体的代码,细节还是较多,等有空打完了在贴,欢迎大神指正







大整数乘法

标签:数学   算法   c++   大数乘法   

原文地址:http://blog.csdn.net/tdap_algorithm_learn/article/details/45399157

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!