加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

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

发布时间:2020-12-14 03:57:39 所属栏目:大数据 来源:网络整理
导读:点击打开链接 方法(一): 关于大数乘法,可以使用数组来模拟小学三年级的乘法竖式计算过程,代码如下: [cpp] ? view plain copy #include?"iostream" ?? #include?"string" ?? using ? namespace ?std;?? int ?main( void )?? {?? ???? char ?str1[1000],

点击打开链接

方法(一):

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

[cpp]? view plain copy
  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=int[len2];??
  18. ????len=len1*len2+1;??
  19. int?*result=?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. ????cout<<"两个大整数相乘的结果为:";??
  39. for(i=len-1;i>=0;i--)??
  40. if(flag)??
  41. ????????????cout<<result[i];??
  42. else?if(result[i]!=0)??
  43. ????????{??
  44. ????????????cout<<result[i];??
  45. ????????????flag=true;??
  46. ????????}??
  47. ????}??
  48. ????cout<<endl;??
  49. delete?[]a;??
  50. delete?[]b;??
  51. delete?[]result;??
  52. ????system("pause");??
  53. return?0;??
  54. }??

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

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

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

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

代码如下:

copy

  1. #include?"iostream"??
  2. #include?"list"??
  3. #include?"string"??
  4. namespace?std;??
  5. ??
  6. /*******大整数减法*********/? ? ? ? ? ? ? ? ? ? ? ? ? //选择list容器是因为要进行频繁的插入操作
  7. list<char>?long_sub(list<char>?clist1,?list<char>?clist2);??
  8. /*******大整数加法*********/??
  9. char>?long_add(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. ????????clist1.erase(clist1.begin());??
  28. ????????clist2.erase(clist2.begin());??
  29. ????????rs?=?long_add(clist1,clist2);??
  30. ????????rs.push_front('-');??
  31. if?(?*(clist1.begin())?!=?'-'?&&?*(clist2.begin())?!=?'-'?)??
  32. ????????//首先保证两数位数相同(填充0)??
  33. ????????int???length1?=?clist1.size();??
  34. ????????int???length2?=?clist2.size();??
  35. if(?length1?<?length2?)??
  36. ????????{??
  37. ????????????for(int?i=0;?i<(length2?-length1);?++i)??
  38. ????????????{??
  39. ????????????????clist1.push_front('0');??
  40. ????????????}??
  41. ????????}??
  42. if?(?length1?>?length2?)??
  43. ????????{??
  44. ????????????int?i=0;?i<(length1?-length2);?++i)??
  45. ????????????{??
  46. ????????????????clist2.push_front('0');??
  47. ????????????}??
  48. ????????}??
  49. ??
  50. //整数加法,从低位加起,最低位的进位初始为0??
  51. int???c=0;?//低位借位初始为0??
  52. int???low;?//减完后本位的数值??
  53. ????????list<char>::iterator?iter1?=?clist1.end();??
  54. ????????--iter1;??
  55. char>::iterator?iter2?=?clist2.end();??
  56. ????????--iter2;??
  57. for(;?iter1!=clist1.begin()?&&?iter2!=clist2.begin();--iter1,--iter2)??
  58. ????????????int???num1?=?*iter1?-'0';??
  59. ????????????int???num2?=?*iter2?-'0';??
  60. ????????????low?=?(num1+num2+c)%10;??
  61. ????????????c?=?(num1+num2+c)/10;??
  62. ????????????rs.push_front(low+'0');//因为list容器里面是char型所以存入的时候要以整数的ascii码存入
  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. if?(?c?!=?0?)??
  70. ????????????rs.push_front(c+'0');??
  71. }??
  72. ??
  73. /*******大整数减法*********/??
  74. list<char>?clist2)??
  75. {??
  76. ????list<//存放最后的结果??
  77. //如果一正一负相减,做相加??
  78. if?(*(clist1.begin())?!=?'-'?&&?*(clist2.begin())?==?'-'?)??
  79. ????????rs?=?long_add(clist1,0); background-color:inherit">//如果一负一正相减,做相加(添符号)??
  80. ????????rs???=?long_add(clist1,?clist2);??
  81. //如果两负相减,作相减??
  82. if?(?*(clist1.begin())?==?'-'?&&?*(clist2.begin())?==?'-'?)??
  83. ????????clist1.erase(clist1.begin());??
  84. ????????clist2.erase(clist2.begin());??? ????????rs?=?long_sub(clist2,?clist1);??
  85. //如果两正相减,做相减??
  86. if?(?*(clist1.begin())?!=?'-'?&&?*(clist2.begin())?!=?'-'?)??
  87. int???sign?=?-1;???//代表两数相减结果的正负,如果最高位为'-'(ascii码为45)表示负,否则表示正??
  88. //首先保证加数位数相同(填充0)??
  89. ????????????sign?=?'-';??
  90. int?i=0;?i<(length2?-length1);?++i)??
  91. ????????????????clist1.push_front('0');??
  92. if?(?length1?>?length2?)??
  93. int?i=0;?i<(length1?-length2);?++i)??
  94. ????????????????clist2.push_front('0');??
  95. if?(?*(clist1.begin())?<?*(clist2.begin())?)??
  96. ????????????sign?=?'-';??
  97. //整数减法,从低位减起,最低位的借位初始为0??
  98. int???c?=?0;?if?(sign?!=?'-'?)??
  99. ???????????????? ????????????????int???c_new?=?0;?//向高位的借位??
  100. ????????????????if?(?num1?<?num2+c?)??
  101. ????????????????{??
  102. ????????????????????c_new?=?1;??
  103. ????????????????????num1?=?num1+10;??
  104. ????????????????}??
  105. ????????????????low?=?(num1-num2-c)%10;??
  106. ????????????????c?=?c_new;??
  107. ????????????????rs.push_front(low+'0');??
  108. ????????????//双方最高位相减的处理??
  109. ????????????low?=?(num1-num2-c)%10;??
  110. if?(?low?!=?0?)??
  111. if?(?sign?==?'-'?)??
  112. //向高位的借位??
  113. ????????????????if?(?num2?<?num1+c?)??
  114. ????????????????{??
  115. ????????????????????c_new?=?1;??
  116. ????????????????????num2?=?num2+10;??
  117. ????????????????}??
  118. ????????????????low?=?(num2-num1-c)%10;??
  119. ????????????????c?=?c_new;??
  120. ????????????????rs.push_front(low+'0');??
  121. ????????????//双方最高位相减的处理??
  122. ????????????low?=?(num2-num1-c)%10;??
  123. if?(?low?!=?0?)??
  124. ????????????rs.push_front('-');?//最高位的'-'作为负数的标志??
  125. }??
  126. /*******大整数乘法*********/??
  127. char>?long_mul(list<char>?rs;???//保存最后的结果??
  128. //递归出口??
  129. if(clist1.size()?==?1?&&?clist2.size()?==?1)???//两个数都成1位了??
  130. int?num1?=?*(clist1.begin())-'0';??
  131. int?num2?=?*(clist2.begin())-'0';??
  132. int???high?=?(num1*num2)/10;???//积的高位??
  133. int???low???=?(num1*num2)%10;???//积的低位??
  134. if?(?high?!=?0?)??
  135. ????????????rs.push_back(high+'0');??
  136. ????????rs.push_back(low+'0');??
  137. if?(clist1.size()?==?1?&&?clist2.size()?>?1)??
  138. int?sign?=?-1;?//最后结果的正负标志,'-'(ascii码为45)表示负,其他表示正??
  139. char?high_bit2?=?*(clist2.begin());?//clist2的最高位??
  140. if?(?high_bit2?==?'-'?)??
  141. ????????????sign?=?'-';?//相乘结果为负??
  142. ????????????clist2.erase(clist2.begin());?//去掉高位的'-'??
  143. int?length2?=?clist2.size();?//clist2的有效长度(去除'-'号后)??
  144. if?(?length2?>?1?)??
  145. //对clist2进行拆分??
  146. ????????????list<char>???clist2_1;???//高位部分??
  147. ????????????list<char>???clist2_2;???//低位部分??
  148. int?i;??
  149. char>::iterator?iter;??
  150. for?(i=0,iter=clist2.begin();?i<length2/2;?++i,++iter)??
  151. ????????????????clist2_1.push_back(*iter);??
  152. for(;?iter?!=?clist2.end();?++iter)??
  153. ????????????????clist2_2.push_back(*iter);??
  154. char>?rs1;?//高位部分和clist1的积??
  155. char>?rs2;?//低位部分和clist1的积??
  156. ????????????rs1?=?long_mul(clist1,?clist2_1);??
  157. ????????????rs2?=?long_mul(clist1,?clist2_2);??
  158. //对高位积进行移位(末尾添0)??
  159. for(?i=0;?i<clist2_2.size();?++i?)??
  160. ????????????????rs1.push_back('0');??
  161. ????????????rs?=?long_add(rs1,rs2);?//两部分积相加??
  162. if(?sign?==?'-'?)??
  163. ????????????????rs.push_front('-');??
  164. else??
  165. ????????????rs?=?long_mul(clist1,153); background-color:inherit; font-weight:bold">if?(?sign?==?'-'?)??
  166. ????????????????rs.push_front('-');?//结果添上'-'号??
  167. if?(clist1.size()?>1?&&?clist2.size()?==?1)??
  168. //最后结果的正负标志,'-'表示负,其他表示正??
  169. char?high_bit1?=?*(clist1.begin());?//clist1的最高位??
  170. if?(?high_bit1?==?'-'?)??
  171. ????????????clist1.erase(clist1.begin());?int?length1?=?clist1.size();?//clist1的有效长度(去除'-'号后)??
  172. if?(?length1?>?1?)??
  173. //对clist1进行拆分??
  174. char>???clist1_1;???char>???clist1_2;??? ????????????????clist1_1.push_back(*iter);??
  175. for(;?iter?!=?clist1.end();?++iter)??
  176. ????????????????clist1_2.push_back(*iter);??
  177. //高位部分和clist2的积??
  178. //低位部分和clist2的积??
  179. ????????????rs1?=?long_mul(clist1_1,108); list-style:decimal-leading-zero outside; line-height:18px"> ????????????rs2?=?long_mul(clist1_2,153); background-color:inherit; font-weight:bold">for(?i=0;?i<clist1_2.size();?++i?)??
  180. if?(clist1.size()?>1?&&?clist2.size()?>?1?)??
  181. char???high_bit1?=?*(clist1.begin());???char???high_bit2?=?*(clist2.begin());???//clist2的最高位??
  182. if?(?high_bit1?==?'-'???&&?high_bit2?!=?'-'?)??
  183. ????????????sign?=?'-';???//相乘结果为负??
  184. ????????????clist1.erase(clist1.begin());???//去掉高位的'-'??
  185. if?(?high_bit1?!=?'-'?&&?high_bit2?==?'-'?)??
  186. ????????????sign?=?'-';??? ????????????clist2.erase(clist2.begin());???if?(?high_bit1?=='-'?&&?high_bit2?==?'-'?)??
  187. ????????????clist1.erase(clist1.begin());??
  188. ????????????clist2.erase(clist2.begin());????//clist1的有效长度??
  189. //clist2的有效长度??
  190. if?(?length1?==?1?||?length2?==?1?)??
  191. if?(?length1?>?1?&&?length2?>?1?)??
  192. //对clist1和clist2分别进行划分??
  193. char>?clist1_1;???//clist1的高位部分??
  194. char>?clist1_2;???//clist1的低位部分??
  195. char>?clist2_1;???//clist2的高位部分??
  196. char>?clist2_2;???//clist2的低位部分??
  197. for(i=0,153); background-color:inherit; font-weight:bold">for(;?iter!=clist1.end();?++iter)??
  198. for(;?iter!=clist2.end();?++iter)??
  199. char>?rs_hh;???//两个高位相乘的结果??
  200. char>?rs_ll;???//两个低位相乘的结果??
  201. ????????????rs_hh?=?long_mul(clist1_1,0); background-color:inherit">//高位相乘结果移位(末尾添0)??
  202. for(i=0;?i<clist1_2.size()+clist2_2.size();?++i)??
  203. ????????????????rs_hh.push_back('0');??
  204. ????????????rs_ll?=?long_mul(clist1_2,?clist2_2);??
  205. char>?sub1_hl;???//clist1的高位和低位部分的差??
  206. char>?sub2_lh;???//clist2的低位和高位部分的差??
  207. //两个高位分别移位??
  208. for(i=0;?i<clist1_2.size();?++i)??
  209. ????????????????clist1_1.push_back('0');??
  210. for(i=0;?i<clist2_2.size();?++i)??
  211. ????????????????clist2_1.push_back('0');??
  212. ????????????sub1_hl?=?long_sub(clist1_1,?clist1_2);??
  213. ????????????sub2_lh?=?long_sub(clist2_2,?clist2_1);??
  214. char>?rs_sub1_sub2;?//两个差的乘积??
  215. ????????????rs_sub1_sub2?=?long_mul(sub1_hl,?sub2_lh);??
  216. //把几个乘积的结果加起来??
  217. ????????????list<char>?tmp1?=?long_add(rs_hh,?rs_ll);??
  218. ????????????list<char>?tmp2?=?long_add(tmp1,?rs_sub1_sub2);??
  219. ????????????list<char>?tmp3?=?long_add(tmp2,?rs_hh);??
  220. ????????????rs?=?long_add(tmp3,?rs_ll);??
  221. ????????????????rs.push_front('-');??
  222. void)??
  223. char>?clist1;??
  224. char>?clist2;??
  225. ????cout?<<"请您输入2个乘数:?"<<endl;??
  226. ????cout?<<"请您输入被乘数:?";??
  227. ????int?i;??
  228. ????string???str1;??
  229. ????cin?>>?str1;??
  230. for(i=0;?i<str1.size();?++i)??
  231. if?(str1[i]?>=?'0'?&&?str1[i]?<=?'9'?)??
  232. ????????????clist1.push_back(str1[i]);??
  233. else??
  234. ????????????cout?<<"被乘数中的数字只能为0~9"?<<endl;??
  235. ????????????exit(1);??
  236. ????cout?<<"请您输入乘数:?";??
  237. ????string?str2;??
  238. ????cin?>>?str2;??
  239. for(i=0;?i<str2.size();?++i)??
  240. if?(?str2[i]?>=?'0'?&&?str2[i]?<=?'9'?)??
  241. ????????????clist2.push_back(str2[i]);??
  242. ????????????cout?<<"乘数中的数字只能为0~9"?<<endl;??
  243. ????????????exit(1);??
  244. char>?rs?=?long_mul(clist1,clist2);??
  245. ????cout?<<?"两个大整数相乘的积为:?";??
  246. for(list<char>::iterator?iter=rs.begin();?iter!=rs.end();?++iter)??
  247. ????????cout?<<?*iter;??
  248. ????cout?<<endl;??
  249. ????system("pause");??
  250. return?0;??
  251. }??

转自:http://blog.csdn.net/hackbuteer1/article/details/6532490


1.第22行代码进行了倒置操作,是因为这样就把输入的数字的个位放到了a[0],十位放到了a[1]........然后这样从a[0]开始的操作就符合了我们一般进行数学运算的习惯.

2.result[i+j]+=a[i]*b[j];这个是计算两个数乘法的基本运算式子.接下来进行进位操作就好了.

3.rs.push_front(low+'0'); 第68行中low+‘0’是因为list<char>所以存入的时候要以char的形式存入,否则会变成low对应的ascii码的内容。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读