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

(1.1.1.1)大数相乘

发布时间:2020-12-14 02:19:48 所属栏目:大数据 来源:网络整理
导读:方法(一): 关于大数乘法,可以使用数组来模拟小学三年级的乘法竖式计算过程,代码如下: [cpp] ? view plain copy #include?"iostream" ?? #include?"string" ?? using ? namespace ?std;?? int ?main( void )?? {?? ???? char ?str1[1000],str2[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

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

(编辑:李大同)

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

    推荐文章
      热点阅读