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

方法(一):

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

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. #include "iostream"  
  2. #include "string"  
  3. using namespace std;  
  4. int main(void)  
  5. {  
  6.     char str1[1000],str2[1000];  
  7.     int i,j,len1,len2,len;  
  8.     bool flag=false;  
  9.     cout<<"任意两个大数的乘法(用数组来模拟小学三年级的乘法竖式计算过程):"<<endl;  
  10.     cout<<"请输入被乘数:";  
  11.     gets(str1);  
  12.     cout<<"请输入乘数:";  
  13.     gets(str2);  
  14.     len1=strlen(str1);  
  15.     len2=strlen(str2);  
  16.     int *a=new int[len1];  
  17.     int *b=new int[len2];  
  18.     len=len1*len2+1;  
  19.     int *result= new int[len];  
  20.     for(i=0;i<len;i++)  
  21.         result[i]=0;  
  22.     for(i=0;i<len1;i++) //将字符串转换为整数,并倒置过来  
  23.         a[i]=str1[len1-1-i]-'0';  
  24.     for(i=0;i<len2;i++)  
  25.         b[i]=str2[len2-1-i]-'0';  
  26.     for(i=0;i<len1;i++)  //用数组来模拟小学三年级的乘法竖式计算过程  
  27.     {  
  28.         for(j=0;j<len2;j++)  
  29.             result[i+j]+=a[i]*b[j];  
  30.     }  
  31.     for(i=0;i<len;i++)   //处理进位的情况  
  32.     {  
  33.         if(result[i]>9)  
  34.         {  
  35.             result[i+1]+=result[i]/10;  
  36.             result[i]%=10;  
  37.         }  
  38.     }  
  39.     cout<<"两个大整数相乘的结果为:";  
  40.     for(i=len-1;i>=0;i--)  
  41.     {  
  42.         if(flag)  
  43.             cout<<result[i];  
  44.         else if(result[i]!=0)  
  45.         {  
  46.             cout<<result[i];  
  47.             flag=true;  
  48.         }  
  49.     }  
  50.     cout<<endl;  
  51.     delete []a;  
  52.     delete []b;  
  53.     delete []result;  
  54.     system("pause");  
  55.     return 0;  
  56. }  

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

设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次。

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

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

代码如下:

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. #include "iostream"  
  2. #include "list"  
  3. #include "string"  
  4. using namespace std;  
  5.   
  6. /*******大整数减法*********/  
  7. list<char> long_sub(list<char> clist1, list<char> clist2);  
  8. /*******大整数加法*********/  
  9. list<char> long_add(list<char> clist1, list<char> clist2)  
  10. {  
  11.     list<char> rs; //存放最后的结果  
  12.     //如果一个正,一个负,做两数相减  
  13.     if ( *(clist1.begin()) == '-' && *(clist2.begin()) != '-' )  
  14.     {  
  15.         clist1.erase(clist1.begin()); //去掉符号位  
  16.         rs = long_sub(clist2, clist1);  
  17.         return rs;  
  18.     }  
  19.     //如果一个负,一个正,做两数相减  
  20.     if ( *(clist1.begin()) != '-' && *(clist2.begin()) == '-' )  
  21.     {  
  22.         clist2.erase(clist2.begin()); //去掉符号位  
  23.         rs = long_sub(clist1, clist2);  
  24.         return rs;  
  25.     }  
  26.     if ( *(clist1.begin()) == '-' && *(clist2.begin()) == '-' )  
  27.     {  
  28.         clist1.erase(clist1.begin());  
  29.         clist2.erase(clist2.begin());  
  30.         rs = long_add(clist1,clist2);  
  31.         rs.push_front('-');  
  32.         return rs;  
  33.     }  
  34.     if ( *(clist1.begin()) != '-' && *(clist2.begin()) != '-' )  
  35.     {  
  36.         //首先保证两数位数相同(填充0)  
  37.         int   length1 = clist1.size();  
  38.         int   length2 = clist2.size();  
  39.         if( length1 < length2 )  
  40.         {  
  41.             for(int i=0; i<(length2 -length1); ++i)  
  42.             {  
  43.                 clist1.push_front('0');  
  44.             }  
  45.         }  
  46.         else if ( length1 > length2 )  
  47.         {  
  48.             for(int i=0; i<(length1 -length2); ++i)  
  49.             {  
  50.                 clist2.push_front('0');  
  51.             }  
  52.         }  
  53.   
  54.         //整数加法,从低位加起,最低位的进位初始为0  
  55.         int   c=0; //低位借位初始为0  
  56.         int   low; //减完后本位的数值  
  57.   
  58.         list<char>::iterator iter1 = clist1.end();  
  59.         --iter1;  
  60.         list<char>::iterator iter2 = clist2.end();  
  61.         --iter2;  
  62.         for(; iter1!=clist1.begin() && iter2!=clist2.begin();--iter1,--iter2)  
  63.         {  
  64.             int   num1 = *iter1 -'0';  
  65.             int   num2 = *iter2 -'0';  
  66.             low = (num1+num2+c)%10;  
  67.             c = (num1+num2+c)/10;  
  68.             rs.push_front(low+'0');  
  69.         }  
  70.         //双方最高位相加的处理  
  71.         int   num1 = *iter1 -'0';  
  72.         int   num2 = *iter2 -'0';  
  73.         low = (num1+num2+c)%10;  
  74.         c = (num1+num2+c)/10;  
  75.         rs.push_front(low+'0');  
  76.         if ( c != 0 )  
  77.         {  
  78.             rs.push_front(c+'0');  
  79.         }  
  80.         return rs;  
  81.     }  
  82.     return rs;  
  83. }  
  84.   
  85. /*******大整数减法*********/  
  86. list<char> long_sub(list<char> clist1, list<char> clist2)  
  87. {  
  88.     list<char> rs; //存放最后的结果  
  89.     //如果一正一负相减,做相加  
  90.     if (*(clist1.begin()) != '-' && *(clist2.begin()) == '-' )  
  91.     {  
  92.         clist2.erase(clist2.begin()); //去掉符号位  
  93.         rs = long_add(clist1, clist2);  
  94.         return rs;  
  95.     }  
  96.     //如果一负一正相减,做相加(添符号)  
  97.     if ( *(clist1.begin()) == '-' && *(clist2.begin()) != '-' )  
  98.     {  
  99.         clist1.erase(clist1.begin()); //去掉符号位  
  100.         rs   = long_add(clist1, clist2);  
  101.         rs.push_front('-');  
  102.         return rs;  
  103.     }  
  104.     //如果两负相减,作相减  
  105.     if ( *(clist1.begin()) == '-' && *(clist2.begin()) == '-' )  
  106.     {  
  107.         clist1.erase(clist1.begin());  
  108.         clist2.erase(clist2.begin());   //去掉符号位  
  109.         rs = long_sub(clist2, clist1);  
  110.         return rs;  
  111.     }  
  112.     //如果两正相减,做相减  
  113.     if ( *(clist1.begin()) != '-' && *(clist2.begin()) != '-' )  
  114.     {  
  115.         int   sign = -1;   //代表两数相减结果的正负,如果最高位为'-'(ascii码为45)表示负,否则表示正  
  116.         //首先保证加数位数相同(填充0)  
  117.         int   length1 = clist1.size();  
  118.         int   length2 = clist2.size();  
  119.         if( length1 < length2 )  
  120.         {  
  121.             sign = '-';  
  122.             for(int i=0; i<(length2 -length1); ++i)  
  123.             {  
  124.                 clist1.push_front('0');  
  125.             }  
  126.         }  
  127.         else if ( length1 > length2 )  
  128.         {  
  129.             for(int i=0; i<(length1 -length2); ++i)  
  130.             {  
  131.                 clist2.push_front('0');  
  132.             }  
  133.         }  
  134.         else if ( *(clist1.begin()) < *(clist2.begin()) )  
  135.         {  
  136.             sign = '-';  
  137.         }  
  138.         //整数减法,从低位减起,最低位的借位初始为0  
  139.         int   c = 0; //低位借位初始为0  
  140.         int   low; //减完后本位的数值  
  141.   
  142.         list<char>::iterator iter1 = clist1.end();  
  143.         --iter1;  
  144.         list<char>::iterator iter2 = clist2.end();  
  145.         --iter2;  
  146.         if (sign != '-' )  
  147.         {  
  148.             for(; iter1!=clist1.begin() && iter2!=clist2.begin();--iter1,--iter2)  
  149.             {  
  150.                 int   num1 = *iter1 -'0';  
  151.                 int   num2 = *iter2 -'0';  
  152.                 int   c_new = 0; //向高位的借位  
  153.                 if ( num1 < num2+c )  
  154.                 {  
  155.                     c_new = 1;  
  156.                     num1 = num1+10;  
  157.                 }  
  158.                 low = (num1-num2-c)%10;  
  159.                 c = c_new;  
  160.                 rs.push_front(low+'0');  
  161.             }  
  162.             //双方最高位相减的处理  
  163.             int   num1 = *iter1 -'0';  
  164.             int   num2 = *iter2 -'0';  
  165.             low = (num1-num2-c)%10;  
  166.             if ( low != 0 )  
  167.             {  
  168.                 rs.push_front(low+'0');  
  169.             }  
  170.         }  
  171.         else if ( sign == '-' )  
  172.         {  
  173.             for(; iter1!=clist1.begin() && iter2!=clist2.begin();--iter1,--iter2)  
  174.             {  
  175.                 int   num1 = *iter1 -'0';  
  176.                 int   num2 = *iter2 -'0';  
  177.                 int   c_new = 0; //向高位的借位  
  178.                 if ( num2 < num1+c )  
  179.                 {  
  180.                     c_new = 1;  
  181.                     num2 = num2+10;  
  182.                 }  
  183.                 low = (num2-num1-c)%10;  
  184.                 c = c_new;  
  185.                 rs.push_front(low+'0');  
  186.             }  
  187.             //双方最高位相减的处理  
  188.             int   num1 = *iter1 -'0';  
  189.             int   num2 = *iter2 -'0';  
  190.             low = (num2-num1-c)%10;  
  191.             if ( low != 0 )  
  192.             {  
  193.                 rs.push_front(low+'0');  
  194.             }  
  195.             rs.push_front('-'); //最高位的'-'作为负数的标志  
  196.         }  
  197.         return rs;  
  198.     }  
  199.     return rs;  
  200. }  
  201. /*******大整数乘法*********/  
  202. list<char> long_mul(list<char> clist1, list<char> clist2)  
  203. {  
  204.     list<char> rs;   //保存最后的结果  
  205.     //递归出口  
  206.     if(clist1.size() == 1 && clist2.size() == 1)   //两个数都成1位了  
  207.     {  
  208.         int num1 = *(clist1.begin())-'0';  
  209.         int num2 = *(clist2.begin())-'0';  
  210.         int   high = (num1*num2)/10;   //积的高位  
  211.         int   low   = (num1*num2)%10;   //积的低位  
  212.         if ( high != 0 )  
  213.         {  
  214.             rs.push_back(high+'0');  
  215.         }  
  216.         rs.push_back(low+'0');  
  217.         return rs;  
  218.     }  
  219.     if (clist1.size() == 1 && clist2.size() > 1)  
  220.     {  
  221.         int sign = -1; //最后结果的正负标志,'-'(ascii码为45)表示负,其他表示正  
  222.         char high_bit2 = *(clist2.begin()); //clist2的最高位  
  223.         if ( high_bit2 == '-' )  
  224.         {  
  225.             sign = '-'//相乘结果为负  
  226.             clist2.erase(clist2.begin()); //去掉高位的'-'  
  227.         }  
  228.         int length2 = clist2.size(); //clist2的有效长度(去除'-'号后)  
  229.         if ( length2 > 1 )  
  230.         {  
  231.             //对clist2进行拆分  
  232.             list<char>   clist2_1;   //高位部分  
  233.             list<char>   clist2_2;   //低位部分  
  234.             int i;  
  235.             list<char>::iterator iter;  
  236.             for (i=0,iter=clist2.begin(); i<length2/2; ++i,++iter)  
  237.             {  
  238.                 clist2_1.push_back(*iter);  
  239.             }  
  240.             for(; iter != clist2.end(); ++iter)  
  241.             {  
  242.                 clist2_2.push_back(*iter);  
  243.             }  
  244.             list<char> rs1; //高位部分和clist1的积  
  245.             list<char> rs2; //低位部分和clist1的积  
  246.             rs1 = long_mul(clist1, clist2_1);  
  247.             rs2 = long_mul(clist1, clist2_2);  
  248.             //对高位积进行移位(末尾添0)  
  249.             for( i=0; i<clist2_2.size(); ++i )  
  250.             {  
  251.                 rs1.push_back('0');  
  252.             }  
  253.             rs = long_add(rs1,rs2); //两部分积相加  
  254.             if( sign == '-' )  
  255.             {  
  256.                 rs.push_front('-');  
  257.             }  
  258.         }  
  259.         else  
  260.         {  
  261.             rs = long_mul(clist1, clist2);  
  262.             if ( sign == '-' )  
  263.             {  
  264.                 rs.push_front('-'); //结果添上'-'号  
  265.             }  
  266.         }  
  267.         return rs;  
  268.     }  
  269.     if (clist1.size() >1 && clist2.size() == 1)  
  270.     {  
  271.         int sign = -1; //最后结果的正负标志,'-'表示负,其他表示正  
  272.         char high_bit1 = *(clist1.begin()); //clist1的最高位  
  273.         if ( high_bit1 == '-' )  
  274.         {  
  275.             sign = '-'//相乘结果为负  
  276.             clist1.erase(clist1.begin()); //去掉高位的'-'  
  277.         }  
  278.         int length1 = clist1.size(); //clist1的有效长度(去除'-'号后)  
  279.         if ( length1 > 1 )  
  280.         {  
  281.             //对clist1进行拆分  
  282.             list<char>   clist1_1;   //高位部分  
  283.             list<char>   clist1_2;   //低位部分  
  284.             int i;  
  285.             list<char>::iterator iter;  
  286.             for (i=0,iter=clist1.begin(); i<length1/2; ++i,++iter)  
  287.             {  
  288.                 clist1_1.push_back(*iter);  
  289.             }  
  290.             for(; iter != clist1.end(); ++iter)  
  291.             {  
  292.                 clist1_2.push_back(*iter);  
  293.             }  
  294.             list<char> rs1; //高位部分和clist2的积  
  295.             list<char> rs2; //低位部分和clist2的积  
  296.             rs1 = long_mul(clist1_1, clist2);  
  297.             rs2 = long_mul(clist1_2, clist2);  
  298.             //对高位积进行移位(末尾添0)  
  299.             for( i=0; i<clist1_2.size(); ++i )  
  300.             {  
  301.                 rs1.push_back('0');  
  302.             }  
  303.             rs = long_add(rs1,rs2); //两部分积相加  
  304.             if( sign == '-' )  
  305.             {  
  306.                 rs.push_front('-');  
  307.             }  
  308.         }  
  309.         else  
  310.         {  
  311.             rs = long_mul(clist1, clist2);  
  312.             if ( sign == '-' )  
  313.             {  
  314.                 rs.push_front('-'); //结果添上'-'号  
  315.             }  
  316.         }  
  317.         return rs;  
  318.     }  
  319.     if (clist1.size() >1 && clist2.size() > 1 )  
  320.     {  
  321.         int sign = -1; //最后结果的正负标志,'-'表示负,其他表示正  
  322.         char   high_bit1 = *(clist1.begin());   //clist1的最高位  
  323.         char   high_bit2 = *(clist2.begin());   //clist2的最高位  
  324.         if ( high_bit1 == '-'   && high_bit2 != '-' )  
  325.         {  
  326.             sign = '-';   //相乘结果为负  
  327.             clist1.erase(clist1.begin());   //去掉高位的'-'  
  328.         }  
  329.         if ( high_bit1 != '-' && high_bit2 == '-' )  
  330.         {  
  331.             sign = '-';   //相乘结果为负  
  332.             clist2.erase(clist2.begin());   //去掉高位的'-'  
  333.         }  
  334.         if ( high_bit1 =='-' && high_bit2 == '-' )  
  335.         {  
  336.             clist1.erase(clist1.begin());  
  337.             clist2.erase(clist2.begin());    //去掉高位的'-'  
  338.         }  
  339.         int length1 = clist1.size(); //clist1的有效长度  
  340.         int length2 = clist2.size(); //clist2的有效长度  
  341.         if ( length1 == 1 || length2 == 1 )  
  342.         {  
  343.             rs = long_mul(clist1, clist2);  
  344.             if ( sign == '-' )  
  345.             {  
  346.                 rs.push_front('-');  
  347.             }  
  348.         }  
  349.         else if ( length1 > 1 && length2 > 1 )  
  350.         {  
  351.             //对clist1和clist2分别进行划分  
  352.             list<char> clist1_1;   //clist1的高位部分  
  353.             list<char> clist1_2;   //clist1的低位部分  
  354.             list<char> clist2_1;   //clist2的高位部分  
  355.             list<char> clist2_2;   //clist2的低位部分  
  356.             int i;  
  357.             list<char>::iterator iter;  
  358.             for(i=0,iter=clist1.begin(); i<length1/2; ++i,++iter)  
  359.             {  
  360.                 clist1_1.push_back(*iter);  
  361.             }  
  362.             for(; iter!=clist1.end(); ++iter)  
  363.             {  
  364.                 clist1_2.push_back(*iter);  
  365.             }  
  366.             for(i=0,iter=clist2.begin(); i<length2/2; ++i,++iter)  
  367.             {  
  368.                 clist2_1.push_back(*iter);  
  369.             }  
  370.             for(; iter!=clist2.end(); ++iter)  
  371.             {  
  372.                 clist2_2.push_back(*iter);  
  373.             }  
  374.             list<char> rs_hh;   //两个高位相乘的结果  
  375.             list<char> rs_ll;   //两个低位相乘的结果  
  376.             rs_hh = long_mul(clist1_1, clist2_1);  
  377.             //高位相乘结果移位(末尾添0)  
  378.             for(i=0; i<clist1_2.size()+clist2_2.size(); ++i)  
  379.             {  
  380.                 rs_hh.push_back('0');  
  381.             }  
  382.             rs_ll = long_mul(clist1_2, clist2_2);  
  383.             list<char> sub1_hl;   //clist1的高位和低位部分的差  
  384.             list<char> sub2_lh;   //clist2的低位和高位部分的差  
  385.             //两个高位分别移位  
  386.             for(i=0; i<clist1_2.size(); ++i)  
  387.             {  
  388.                 clist1_1.push_back('0');  
  389.             }  
  390.             for(i=0; i<clist2_2.size(); ++i)  
  391.             {  
  392.                 clist2_1.push_back('0');  
  393.             }  
  394.             sub1_hl = long_sub(clist1_1, clist1_2);  
  395.             sub2_lh = long_sub(clist2_2, clist2_1);  
  396.             list<char> rs_sub1_sub2; //两个差的乘积  
  397.             rs_sub1_sub2 = long_mul(sub1_hl, sub2_lh);  
  398.             //把几个乘积的结果加起来  
  399.             list<char> tmp1 = long_add(rs_hh, rs_ll);  
  400.             list<char> tmp2 = long_add(tmp1, rs_sub1_sub2);  
  401.             list<char> tmp3 = long_add(tmp2, rs_hh);  
  402.             rs = long_add(tmp3, rs_ll);  
  403.             if ( sign == '-' )  
  404.             {  
  405.                 rs.push_front('-');  
  406.             }  
  407.         }  
  408.         return rs;  
  409.     }  
  410.     return rs;  
  411. }  
  412.   
  413. int main(void)  
  414. {  
  415.     list<char> clist1;  
  416.     list<char> clist2;  
  417.     cout <<"请您输入2个乘数: "<<endl;  
  418.     cout <<"请您输入被乘数: ";  
  419.     int i;  
  420.     string   str1;  
  421.     cin >> str1;  
  422.     for(i=0; i<str1.size(); ++i)  
  423.     {  
  424.         if (str1[i] >= '0' && str1[i] <= '9' )  
  425.         {  
  426.             clist1.push_back(str1[i]);  
  427.         }  
  428.         else  
  429.         {  
  430.             cout <<"被乘数中的数字只能为0~9" <<endl;  
  431.             exit(1);  
  432.         }  
  433.     }  
  434.     cout <<"请您输入乘数: ";  
  435.     string str2;  
  436.     cin >> str2;  
  437.     for(i=0; i<str2.size(); ++i)  
  438.     {  
  439.         if ( str2[i] >= '0' && str2[i] <= '9' )  
  440.         {  
  441.             clist2.push_back(str2[i]);  
  442.         }  
  443.         else  
  444.         {  
  445.             cout <<"乘数中的数字只能为0~9" <<endl;  
  446.             exit(1);  
  447.         }  
  448.     }  
  449.     list<char> rs = long_mul(clist1,clist2);  
  450.     cout << "两个大整数相乘的积为: ";  
  451.     for(list<char>::iterator iter=rs.begin(); iter!=rs.end(); ++iter)  
  452.     {  
  453.         cout << *iter;  
  454.     }  
  455.     cout <<endl;  
  456.     system("pause");  
  457.     return 0;  


你可能感兴趣的:(c,算法)