任意长度的两个大数的乘法

方法(一):

关于大数乘法,可以使用数组来模拟小学三年级的乘法竖式计算过程,代码如下:

#include "iostream" #include "string" using namespace std; int main(void) { char str1[1000],str2[1000]; int i,j,len1,len2,len; bool flag=false; cout<<"任意两个大数的乘法(用数组来模拟小学三年级的乘法竖式计算过程):"<9) { result[i+1]+=result[i]/10; result[i]%=10; } } cout<<"两个大整数相乘的结果为:"; for(i=len-1;i>=0;i--) { if(flag) cout<

方法(二):关于大数乘法,可以使用大整数乘法的分治方法:

设X和Y都是n位的整数,现在要计算它们的乘积XY。如果
**利用小学所学的方法,将每两个一位数都进行相乘,最后
**再相加,效率比较低下,乘法需要n^2次。分治的方法可以
**减少乘法的次数,设X被分成2部分A和B,即X=A*10^(n/2)+B
**Y也同样处理,即Y=C*10^(n/2)+D.
**那么,XY=(A*10^(n/2)+B)*(C*10^(n/2)+D)
               =AC*10^n+(AD+BC)*10^(n/2)+BD ------>(1)
**AD和BC可以利用AC和BD来表示,AD+BC=(A-B)*(D-C)+AC+BD --->(2)
**这样(1)的乘法次数由4次减少到3次。

**最后的运算效率会有所提高。

***以上出自   计算机算法设计与分析(王晓东) *******/

代码如下:

#include "iostream" #include "list" #include "string" using namespace std; /*******大整数减法*********/ list long_sub(list clist1, list clist2); /*******大整数加法*********/ list long_add(list clist1, list clist2) { list rs; //存放最后的结果 //如果一个正,一个负,做两数相减 if ( *(clist1.begin()) == '-' && *(clist2.begin()) != '-' ) { clist1.erase(clist1.begin()); //去掉符号位 rs = long_sub(clist2, clist1); return rs; } //如果一个负,一个正,做两数相减 if ( *(clist1.begin()) != '-' && *(clist2.begin()) == '-' ) { clist2.erase(clist2.begin()); //去掉符号位 rs = long_sub(clist1, clist2); return rs; } if ( *(clist1.begin()) == '-' && *(clist2.begin()) == '-' ) { clist1.erase(clist1.begin()); clist2.erase(clist2.begin()); rs = long_add(clist1,clist2); rs.push_front('-'); return rs; } if ( *(clist1.begin()) != '-' && *(clist2.begin()) != '-' ) { //首先保证两数位数相同(填充0) int length1 = clist1.size(); int length2 = clist2.size(); if( length1 < length2 ) { for(int i=0; i<(length2 -length1); ++i) { clist1.push_front('0'); } } else if ( length1 > length2 ) { for(int i=0; i<(length1 -length2); ++i) { clist2.push_front('0'); } } //整数加法,从低位加起,最低位的进位初始为0 int c=0; //低位借位初始为0 int low; //减完后本位的数值 list::iterator iter1 = clist1.end(); --iter1; list::iterator iter2 = clist2.end(); --iter2; for(; iter1!=clist1.begin() && iter2!=clist2.begin();--iter1,--iter2) { int num1 = *iter1 -'0'; int num2 = *iter2 -'0'; low = (num1+num2+c)%10; c = (num1+num2+c)/10; rs.push_front(low+'0'); } //双方最高位相加的处理 int num1 = *iter1 -'0'; int num2 = *iter2 -'0'; low = (num1+num2+c)%10; c = (num1+num2+c)/10; rs.push_front(low+'0'); if ( c != 0 ) { rs.push_front(c+'0'); } return rs; } return rs; } /*******大整数减法*********/ list long_sub(list clist1, list clist2) { list rs; //存放最后的结果 //如果一正一负相减,做相加 if (*(clist1.begin()) != '-' && *(clist2.begin()) == '-' ) { clist2.erase(clist2.begin()); //去掉符号位 rs = long_add(clist1, clist2); return rs; } //如果一负一正相减,做相加(添符号) if ( *(clist1.begin()) == '-' && *(clist2.begin()) != '-' ) { clist1.erase(clist1.begin()); //去掉符号位 rs = long_add(clist1, clist2); rs.push_front('-'); return rs; } //如果两负相减,作相减 if ( *(clist1.begin()) == '-' && *(clist2.begin()) == '-' ) { clist1.erase(clist1.begin()); clist2.erase(clist2.begin()); //去掉符号位 rs = long_sub(clist2, clist1); return rs; } //如果两正相减,做相减 if ( *(clist1.begin()) != '-' && *(clist2.begin()) != '-' ) { int sign = -1; //代表两数相减结果的正负,如果最高位为'-'(ascii码为45)表示负,否则表示正 //首先保证加数位数相同(填充0) int length1 = clist1.size(); int length2 = clist2.size(); if( length1 < length2 ) { sign = '-'; for(int i=0; i<(length2 -length1); ++i) { clist1.push_front('0'); } } else if ( length1 > length2 ) { for(int i=0; i<(length1 -length2); ++i) { clist2.push_front('0'); } } else if ( *(clist1.begin()) < *(clist2.begin()) ) { sign = '-'; } //整数减法,从低位减起,最低位的借位初始为0 int c = 0; //低位借位初始为0 int low; //减完后本位的数值 list::iterator iter1 = clist1.end(); --iter1; list::iterator iter2 = clist2.end(); --iter2; if (sign != '-' ) { for(; iter1!=clist1.begin() && iter2!=clist2.begin();--iter1,--iter2) { int num1 = *iter1 -'0'; int num2 = *iter2 -'0'; int c_new = 0; //向高位的借位 if ( num1 < num2+c ) { c_new = 1; num1 = num1+10; } low = (num1-num2-c)%10; c = c_new; rs.push_front(low+'0'); } //双方最高位相减的处理 int num1 = *iter1 -'0'; int num2 = *iter2 -'0'; low = (num1-num2-c)%10; if ( low != 0 ) { rs.push_front(low+'0'); } } else if ( sign == '-' ) { for(; iter1!=clist1.begin() && iter2!=clist2.begin();--iter1,--iter2) { int num1 = *iter1 -'0'; int num2 = *iter2 -'0'; int c_new = 0; //向高位的借位 if ( num2 < num1+c ) { c_new = 1; num2 = num2+10; } low = (num2-num1-c)%10; c = c_new; rs.push_front(low+'0'); } //双方最高位相减的处理 int num1 = *iter1 -'0'; int num2 = *iter2 -'0'; low = (num2-num1-c)%10; if ( low != 0 ) { rs.push_front(low+'0'); } rs.push_front('-'); //最高位的'-'作为负数的标志 } return rs; } return rs; } /*******大整数乘法*********/ list long_mul(list clist1, list clist2) { list rs; //保存最后的结果 //递归出口 if(clist1.size() == 1 && clist2.size() == 1) //两个数都成1位了 { int num1 = *(clist1.begin())-'0'; int num2 = *(clist2.begin())-'0'; int high = (num1*num2)/10; //积的高位 int low = (num1*num2)%10; //积的低位 if ( high != 0 ) { rs.push_back(high+'0'); } rs.push_back(low+'0'); return rs; } if (clist1.size() == 1 && clist2.size() > 1) { int sign = -1; //最后结果的正负标志,'-'(ascii码为45)表示负,其他表示正 char high_bit2 = *(clist2.begin()); //clist2的最高位 if ( high_bit2 == '-' ) { sign = '-'; //相乘结果为负 clist2.erase(clist2.begin()); //去掉高位的'-' } int length2 = clist2.size(); //clist2的有效长度(去除'-'号后) if ( length2 > 1 ) { //对clist2进行拆分 list clist2_1; //高位部分 list clist2_2; //低位部分 int i; list::iterator iter; for (i=0,iter=clist2.begin(); i rs1; //高位部分和clist1的积 list rs2; //低位部分和clist1的积 rs1 = long_mul(clist1, clist2_1); rs2 = long_mul(clist1, clist2_2); //对高位积进行移位(末尾添0) for( i=0; i1 && clist2.size() == 1) { int sign = -1; //最后结果的正负标志,'-'表示负,其他表示正 char high_bit1 = *(clist1.begin()); //clist1的最高位 if ( high_bit1 == '-' ) { sign = '-'; //相乘结果为负 clist1.erase(clist1.begin()); //去掉高位的'-' } int length1 = clist1.size(); //clist1的有效长度(去除'-'号后) if ( length1 > 1 ) { //对clist1进行拆分 list clist1_1; //高位部分 list clist1_2; //低位部分 int i; list::iterator iter; for (i=0,iter=clist1.begin(); i rs1; //高位部分和clist2的积 list rs2; //低位部分和clist2的积 rs1 = long_mul(clist1_1, clist2); rs2 = long_mul(clist1_2, clist2); //对高位积进行移位(末尾添0) for( i=0; i1 && clist2.size() > 1 ) { int sign = -1; //最后结果的正负标志,'-'表示负,其他表示正 char high_bit1 = *(clist1.begin()); //clist1的最高位 char high_bit2 = *(clist2.begin()); //clist2的最高位 if ( high_bit1 == '-' && high_bit2 != '-' ) { sign = '-'; //相乘结果为负 clist1.erase(clist1.begin()); //去掉高位的'-' } if ( high_bit1 != '-' && high_bit2 == '-' ) { sign = '-'; //相乘结果为负 clist2.erase(clist2.begin()); //去掉高位的'-' } if ( high_bit1 =='-' && high_bit2 == '-' ) { clist1.erase(clist1.begin()); clist2.erase(clist2.begin()); //去掉高位的'-' } int length1 = clist1.size(); //clist1的有效长度 int length2 = clist2.size(); //clist2的有效长度 if ( length1 == 1 || length2 == 1 ) { rs = long_mul(clist1, clist2); if ( sign == '-' ) { rs.push_front('-'); } } else if ( length1 > 1 && length2 > 1 ) { //对clist1和clist2分别进行划分 list clist1_1; //clist1的高位部分 list clist1_2; //clist1的低位部分 list clist2_1; //clist2的高位部分 list clist2_2; //clist2的低位部分 int i; list::iterator iter; for(i=0,iter=clist1.begin(); i rs_hh; //两个高位相乘的结果 list rs_ll; //两个低位相乘的结果 rs_hh = long_mul(clist1_1, clist2_1); //高位相乘结果移位(末尾添0) for(i=0; i sub1_hl; //clist1的高位和低位部分的差 list sub2_lh; //clist2的低位和高位部分的差 //两个高位分别移位 for(i=0; i rs_sub1_sub2; //两个差的乘积 rs_sub1_sub2 = long_mul(sub1_hl, sub2_lh); //把几个乘积的结果加起来 list tmp1 = long_add(rs_hh, rs_ll); list tmp2 = long_add(tmp1, rs_sub1_sub2); list tmp3 = long_add(tmp2, rs_hh); rs = long_add(tmp3, rs_ll); if ( sign == '-' ) { rs.push_front('-'); } } return rs; } return rs; } int main(void) { list clist1; list clist2; cout <<"请您输入2个乘数: "<> str1; for(i=0; i= '0' && str1[i] <= '9' ) { clist1.push_back(str1[i]); } else { cout <<"被乘数中的数字只能为0~9" <> str2; for(i=0; i= '0' && str2[i] <= '9' ) { clist2.push_back(str2[i]); } else { cout <<"乘数中的数字只能为0~9" < rs = long_mul(clist1,clist2); cout << "两个大整数相乘的积为: "; for(list::iterator iter=rs.begin(); iter!=rs.end(); ++iter) { cout << *iter; } cout <

你可能感兴趣的:(C/C++)