大数乘法即多项式乘法问题,求A(x)与B(x)的乘积C(x),朴素解法的复杂度O(n^2),基本思想是把多项式A(x)与B(x)写成

A(x)=a*x^m+b
B(x)=c*x^m+d

其中a,b,c,d为x的多项式。
则A(x)*B(x)=(ac)*x^2m+(ad+bc)*x^m+bd
由ad+bc=(a+b)(c+d)-ac-bd
原来的4次乘法和1次加法由3次乘法和2次减法代替,减少了一次乘法操作。
用同样的方法应用到abcd的乘法上。

(以上内容摘自互联网)

以下为用java实现的代码:

  1. package com.kyy.sf;
  2.  
  3. public class BigInteger {
  4.  
  5. public BigInteger() {
  6.  
  7. }
  8.  
  9. // 基本思想是把多项式A(x)与B(x)写成
  10. // A(x)=a*x^m+b
  11. // B(x)=c*x^m+d
  12. // 其中a,b,c,d为x的多项式。
  13. // 则A(x)*B(x)=(ac)*x^2m+(ad+bc)*x^m+bd
  14. // 由ad+bc=(a+b)(c+d)-ac-bd
  15. // 字符串模拟乘法操作
  16.  
  17. public static String mut(String x, String y) {
  18. // deep++;// Console.WriteLine("-" + deep + "-");
  19. String negative = "";
  20. // x,y同为正或者同为负
  21. if ((x.startsWith("-") && y.startsWith("-"))
  22. || (!x.startsWith("-") && !y.startsWith("-"))) {
  23. x = x.replaceAll("-", "");
  24. y = y.replaceAll("-", "");
  25. negative = "";
  26. }// x,y一正一负
  27. else if ((x.startsWith("-") && !y.startsWith("-"))
  28. || (!x.startsWith("-") && y.startsWith("-"))) {
  29. x = x.replace("-", "");
  30. y = y.replace("-", "");
  31. negative = "-";
  32. }
  33.  
  34. // 如果长度都等于于9,直接相乘,返回就行了。
  35. if (x.length() == 1 && y.length() == 1) {
  36. // 计算乘积
  37. int tmp = (Integer.parseInt(x) * Integer.parseInt(y));
  38.  
  39. if (tmp == 0) {
  40. return tmp + "";
  41. } else {
  42. return negative + tmp;
  43. }
  44. }
  45.  
  46. // 公式里的abcd
  47. String a, b, c, d;
  48. if (x.length() == 1) {
  49. a = "0";
  50. b = x;
  51. } else {
  52. if (x.length() % 2 != 0) {
  53. x = "0" + x;
  54. }
  55. a = x.substring(0, x.length() / 2);
  56. b = x.substring(x.length() / 2);
  57. }
  58. if (y.length() == 1) {
  59. c = "0";
  60. d = y;
  61. } else {
  62. if (y.length() % 2 != 0) {
  63. y = "0" + y;
  64. }
  65. c = y.substring(0, y.length() / 2);
  66. d = y.substring(y.length() / 2);
  67. }
  68. // 按最大位数取值,以确定补零数目
  69. int n = x.length() >= y.length() ? x.length() : y.length();
  70.  
  71. String t1, t2, t3;
  72. // 递归调用,根据公式计算出值。
  73. String ac = mut(a, c);
  74. String bd = mut(b, d);
  75. t1 = mut(sub(a, b), sub(d, c));
  76. t2 = add(add(t1, ac), bd);
  77. t3 = add(add(Power10(ac, n), Power10(t2, n / 2)), bd).replaceAll("^0+",
  78. "");
  79.  
  80. if (t3 == "")
  81. return "0";
  82. return negative + t3;
  83. }
  84.  
  85. private static String add(String x, String y) {
  86.  
  87. if (x.startsWith("-") && !y.startsWith("-")) {
  88. return sub(y, x.replaceAll("^-", ""));
  89. } else if (!x.startsWith("-") && y.startsWith("-")) {
  90. return sub(x, y.replaceAll("^-", ""));
  91. } else if (x.startsWith("-") && y.startsWith("-")) {
  92. return "-" + add(x.replaceAll("^-", ""), y.replaceAll("^-", ""));
  93. }
  94.  
  95. if (x.length() > y.length()) {
  96. y = format(y, x.length(), "0");
  97. } else {
  98. x = format(x, y.length(), "0");
  99. }
  100. int[] sum = new int[x.length() + 1];
  101.  
  102. for (int i = x.length() - 1; i >= 0; i--) {
  103. int tmpsum = Integer.parseInt(x.charAt(i) + "")
  104. + Integer.parseInt(y.charAt(i) + "") + sum[i + 1];
  105. if (tmpsum >= 10) {
  106. sum[i + 1] = tmpsum - 10;
  107. sum[i] = 1;// 表示进位
  108. } else {
  109. sum[i + 1] = tmpsum;
  110. }
  111. }
  112.  
  113. StringBuilder returnvalue = new StringBuilder();
  114.  
  115. for (int i : sum) {
  116. returnvalue.append(i);
  117. }
  118.  
  119. if (sum[0] == 1) {
  120.  
  121. return returnvalue.toString();
  122.  
  123. } else {
  124. return returnvalue.replace(0, 1, "").toString();
  125. }
  126.  
  127. }
  128.  
  129. // 字符串模拟减法操作
  130. private static String sub(String x, String y) {
  131.  
  132. // x是正数,y也是正数
  133. int flag = checkBigger(x, y);
  134.  
  135. if (flag == 0) {
  136. return "0";
  137. } else if (flag == -1) {
  138. String tmp = y;
  139. y = x;
  140. x = tmp;
  141. }
  142. // 保证了x>=y
  143. y = format(y, x.length(), "0");// y补0与x对齐
  144.  
  145. int[] difference = new int[x.length()];
  146.  
  147. for (int i = x.length() - 1; i >= 0; i--) {
  148.  
  149. int tmpdifference;
  150.  
  151. tmpdifference = Integer.parseInt(x.charAt(i) + "")
  152. - Integer.parseInt(y.charAt(i) + "") + difference[i];
  153.  
  154. if (tmpdifference < 0) {
  155.  
  156. tmpdifference += 10;
  157. difference[i - 1] = -1;// 表示进位
  158. }
  159.  
  160. difference[i] = tmpdifference;
  161. }
  162.  
  163. StringBuilder returnvalue = new StringBuilder();
  164.  
  165. for (int i : difference) {
  166. returnvalue.append(i);
  167. }
  168.  
  169. String rv = returnvalue.toString().replaceAll("^0+", "");
  170.  
  171. if ("".equals(rv)) {
  172. return "0";
  173. }
  174.  
  175. if (flag == -1) {
  176. rv = "-" + rv;
  177. }
  178.  
  179. return rv;
  180. }
  181.  
  182. // 比较大小
  183. private static int checkBigger(String x, String y) {
  184.  
  185. if (x.length() > y.length()) {
  186.  
  187. return 1;
  188.  
  189. } else if (x.length() < y.length()) {
  190.  
  191. return -1;
  192.  
  193. } else {
  194.  
  195. for (int i = 0; i < x.length(); i++) {
  196.  
  197. if (x.charAt(i) > y.charAt(i)) {
  198.  
  199. return 1;
  200.  
  201. } else if (x.charAt(i) < y.charAt(i)) {
  202. return -1;
  203. }
  204. }
  205.  
  206. return 0;
  207. }
  208. }
  209.  
  210. //数据前补零
  211. private static String format(String str, int len, String fu) {
  212.  
  213. len = len - str.length();
  214.  
  215. for (int i = 0; i < len; i++) {
  216.  
  217. str = fu + str;
  218. }
  219.  
  220. return str;
  221.  
  222. }
  223.  
  224. // 模拟移位
  225. public static String Power10(String num, int n) {
  226.  
  227. for (int i = 0; i < n; i++) {
  228.  
  229. num += "0";
  230.  
  231. }
  232.  
  233. return num;
  234. }
  235.  
  236. public static void main(String[] args) {
  237.  
  238. String x = "93859048059849086850986804750894758903278473894578397598475984784857487584758094875890475984955624146039530798877974";
  239. String y = "224343444859408590475847538946";
  240. System.out.println(mut(x, y));
  241.  
  242. System.out.println(mut("1111111111", "1111111111"));
  243.  
  244. }
  245. }

用分治法实现大数乘法,加法,减法(java实现)的更多相关文章

  1. 51 Nod 1028 大数乘法 V2【Java大数乱搞】

    1028 大数乘法 V2 基准时间限制:2 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 给出2个大整数A,B,计算A*B的结果. Input 第1行:大数A 第2行:大数B (A ...

  2. 剑指offer编程题Java实现——面试题12相关题大数的加法、减法、乘法问题的实现

    用字符串或者数组表示大数是一种很简单有效的表示方式.在打印1到最大的n为数的问题上采用的是使用数组表示大数的方式.在相关题实现任意两个整数的加法.减法.乘法的实现中,采用字符串对大数进行表示,不过在具 ...

  3. 分治法(一)(zt)

    这篇文章将讨论: 1) 分治策略的思想和理论 2) 几个分治策略的例子:合并排序,快速排序,折半查找,二叉遍历树及其相关特性. 说明:这几个例子在前面都写过了,这里又拿出来,从算法设计的策略的角度把它 ...

  4. hdu_1042(模拟大数乘法)

    计算n! #include<cstring> #include<cstdio> using namespace std; ]; int main() { int n; whil ...

  5. PAT 1023 Have Fun with Numbers[大数乘法][一般]

    1023 Have Fun with Numbers (20)(20 分) Notice that the number 123456789 is a 9-digit number consistin ...

  6. 分治法 - Divide and Conquer

    在计算机科学中,分治法是一种很重要的算法.分治法即『分而治之』,把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的 ...

  7. Project Euler 16 Power digit sum( 大数乘法 )

    题意: 215 = 32768,而32768的各位数字之和是 3 + 2 + 7 + 6 + 8 = 26. 21000的各位数字之和是多少? 思路:大数乘法,计算 210 × 100 可加速计算,每 ...

  8. Java算法——分治法

         一.基本概念 在计算机科学中,分治法是一种很重要的算法.字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简 ...

  9. 分治法求解最近对问题(c++)

    #include"stdafx.h" #include<iostream> #include<cmath> #define TRUE 1 #define F ...

随机推荐

  1. window 便笺

    windows的便签很方便人们记录日常工作安排,但是不是所有人都知道如何调用,下面介绍下如何调用windows便签: 1.win + R -->  StikyNot 2.弹出便签界面 3.右击底 ...

  2. Mysql 培训

     1. Mysql 培训 1.1. 培训目的 本文档是针对MySQL 数据库方面的基础培训,为了使项目组成员能够达到使用MySQL 数据库的目的. 1.2. 培训对象 开发者 1.3. 经常使用词及符 ...

  3. iOS开发——新特性Swift篇&Swift 2.0 异常处理

    Swift 2.0 异常处理 WWDC 2015 宣布了新的 Swift 2.0. 这次重大更新给 Swift 提供了新的异常处理方法.这篇文章会主要围绕这个方面进行讨论. 如何建造异常类型? 在 i ...

  4. stap-prep 需要安装那些内核符号

    [root@server-mysql ~]# Need to install the following packages:kernel-debuginfo-2.6.32-279.el6.x86_64 ...

  5. dd,实现系统备份

    一.dd的使用 dd命令的解释dd:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换. 注意:指定数字的地方若以下列字符结尾则乘以相应的数字:b=512:c=1:k=1024:w=2 参数: ...

  6. iOS开发几年了,你清楚OC中的这些东西么1

    前言 几年前笔者是使用Objective-C进行iOS开发, 不过在两年前Apple发布swift的时候,就开始了swift的学习, 在swift1.2发布后就正式并且一直都使用了swift进行iOS ...

  7. SerialPort基本小例

    SerialPort是用于串口通信的控件与VB6中的MSCOMM控件相似,使用很方便... vb.net CodeImports System.IO.PortsImports System.TextP ...

  8. JS类型(1)_JS学习笔记(2016.10.02)

    js类型 js中的数据类型有undefined,boolean,number,string,null,object等6种,前5种为原始类型(基本类型),基本类型的访问是按值访问的,就是说你可以操作保存 ...

  9. Android_Spinner_example

    xml数据: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns ...

  10. CSS选择器优先级

    1.类的覆盖顺序和应用的时候引用的顺序没关系,覆盖顺序取决于类定义的顺序     例如: .a{ color:red } .b{ color:green }     由于b晚于a定义,所以b覆盖a,反 ...