大数乘法即多项式乘法问题,求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实现的代码:

 package com.kyy.sf;

 public class BigInteger {

     public BigInteger() {

     }

     // 基本思想是把多项式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
// 字符串模拟乘法操作 public static String mut(String x, String y) {
// deep++;// Console.WriteLine("-" + deep + "-");
String negative = "";
// x,y同为正或者同为负
if ((x.startsWith("-") && y.startsWith("-"))
|| (!x.startsWith("-") && !y.startsWith("-"))) {
x = x.replaceAll("-", "");
y = y.replaceAll("-", "");
negative = "";
}// x,y一正一负
else if ((x.startsWith("-") && !y.startsWith("-"))
|| (!x.startsWith("-") && y.startsWith("-"))) {
x = x.replace("-", "");
y = y.replace("-", "");
negative = "-";
} // 如果长度都等于于9,直接相乘,返回就行了。
if (x.length() == 1 && y.length() == 1) {
// 计算乘积
int tmp = (Integer.parseInt(x) * Integer.parseInt(y)); if (tmp == 0) {
return tmp + "";
} else {
return negative + tmp;
}
} // 公式里的abcd
String a, b, c, d;
if (x.length() == 1) {
a = "0";
b = x;
} else {
if (x.length() % 2 != 0) {
x = "0" + x;
}
a = x.substring(0, x.length() / 2);
b = x.substring(x.length() / 2);
}
if (y.length() == 1) {
c = "0";
d = y;
} else {
if (y.length() % 2 != 0) {
y = "0" + y;
}
c = y.substring(0, y.length() / 2);
d = y.substring(y.length() / 2);
}
// 按最大位数取值,以确定补零数目
int n = x.length() >= y.length() ? x.length() : y.length(); String t1, t2, t3;
// 递归调用,根据公式计算出值。
String ac = mut(a, c);
String bd = mut(b, d);
t1 = mut(sub(a, b), sub(d, c));
t2 = add(add(t1, ac), bd);
t3 = add(add(Power10(ac, n), Power10(t2, n / 2)), bd).replaceAll("^0+",
""); if (t3 == "")
return "0";
return negative + t3;
} private static String add(String x, String y) { if (x.startsWith("-") && !y.startsWith("-")) {
return sub(y, x.replaceAll("^-", ""));
} else if (!x.startsWith("-") && y.startsWith("-")) {
return sub(x, y.replaceAll("^-", ""));
} else if (x.startsWith("-") && y.startsWith("-")) {
return "-" + add(x.replaceAll("^-", ""), y.replaceAll("^-", ""));
} if (x.length() > y.length()) {
y = format(y, x.length(), "0");
} else {
x = format(x, y.length(), "0");
}
int[] sum = new int[x.length() + 1]; for (int i = x.length() - 1; i >= 0; i--) {
int tmpsum = Integer.parseInt(x.charAt(i) + "")
+ Integer.parseInt(y.charAt(i) + "") + sum[i + 1];
if (tmpsum >= 10) {
sum[i + 1] = tmpsum - 10;
sum[i] = 1;// 表示进位
} else {
sum[i + 1] = tmpsum;
}
} StringBuilder returnvalue = new StringBuilder(); for (int i : sum) {
returnvalue.append(i);
} if (sum[0] == 1) { return returnvalue.toString(); } else {
return returnvalue.replace(0, 1, "").toString();
} } // 字符串模拟减法操作
private static String sub(String x, String y) { // x是正数,y也是正数
int flag = checkBigger(x, y); if (flag == 0) {
return "0";
} else if (flag == -1) {
String tmp = y;
y = x;
x = tmp;
}
// 保证了x>=y
y = format(y, x.length(), "0");// y补0与x对齐 int[] difference = new int[x.length()]; for (int i = x.length() - 1; i >= 0; i--) { int tmpdifference; tmpdifference = Integer.parseInt(x.charAt(i) + "")
- Integer.parseInt(y.charAt(i) + "") + difference[i]; if (tmpdifference < 0) { tmpdifference += 10;
difference[i - 1] = -1;// 表示进位
} difference[i] = tmpdifference;
} StringBuilder returnvalue = new StringBuilder(); for (int i : difference) {
returnvalue.append(i);
} String rv = returnvalue.toString().replaceAll("^0+", ""); if ("".equals(rv)) {
return "0";
} if (flag == -1) {
rv = "-" + rv;
} return rv;
} // 比较大小
private static int checkBigger(String x, String y) { if (x.length() > y.length()) { return 1; } else if (x.length() < y.length()) { return -1; } else { for (int i = 0; i < x.length(); i++) { if (x.charAt(i) > y.charAt(i)) { return 1; } else if (x.charAt(i) < y.charAt(i)) {
return -1;
}
} return 0;
}
} //数据前补零
private static String format(String str, int len, String fu) { len = len - str.length(); for (int i = 0; i < len; i++) { str = fu + str;
} return str; } // 模拟移位
public static String Power10(String num, int n) { for (int i = 0; i < n; i++) { num += "0"; } return num;
} public static void main(String[] args) { String x = "93859048059849086850986804750894758903278473894578397598475984784857487584758094875890475984955624146039530798877974";
String y = "224343444859408590475847538946";
System.out.println(mut(x, y)); System.out.println(mut("1111111111", "1111111111")); }
}

用分治法实现大数乘法,加法,减法(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. 编写一个Java应用程序,该程序包括3个类:Monkey类、People类和主类 E。要求: (1) Monkey类中有个构造方法:Monkey (String s),并且有个public void speak() 方法,在speak方法中输出“咿咿呀呀......”的信息。 (2)People类是Monkey类的子类,在People类中重写方法speak(),在speak方法 中输出“小样的,不

    package homework1; public class Monkey { //构造方法 Monkey(String s) { } //成员方法 public void speak() { Sy ...

  2. Start-Process传递变量

    如果$b="aa,bb" Start-Process PowerShell.exe -Argumentlist "d:\w.ps1 $a $b $c" Star ...

  3. 多边形背景生成工具推荐-Trianglify

    前端开发whqet,csdn,王海庆,whqet,前端开发专家 low poly低多边形(相似于折纸的效果),多边形风格的设计应用越来越多,今天我们就来看一个利用d3.js写成的生成器Triangli ...

  4. 【44】将与参数无关的代码抽离templates

    1.template是产生代码的代码,这就意味着源码看起来很少,生成的目标码大量膨胀. 2.考虑,如果两个方法有重复代码,我们会新建一个方法,把重复的代码放进去,原先两个方法调用第三个方法.如果两个类 ...

  5. 修改LiteIDE 编辑窗口的主题

    用习惯了Visual Studio 再看其他编译器总是有点别扭,当然LiteIDE 也是能够自定义主题的,再次感叹作者的用心. 依次: 查看 -> 选项 -> LiteEditor 在编辑 ...

  6. iOS开发——高级技术&摇一摇功能的实现

    摇一摇功能的实现 在AppStore中多样化功能越来越多的被使用了,所以今天就开始介绍一些iOS开发的比较实用,但是我们接触的比较少的功能,我们先从摇一摇功能开始 在 UIResponder中存在这么 ...

  7. android136 360 拖拽

    差补器原理: 图标拖拽:     activity_drag_view.xml <?xml version="1.0" encoding="utf-8"? ...

  8. IE jquery mouseenter,mouseover超奇葩问题

    做了个项目,结构很简单 <div class="index-main" data-url="./img/index_default.jpg"> &l ...

  9. LLBLGen代码生成工具

    LLBLGen代码生成工具 下载地址:http://www.llblgen.com/ 最新版本4.2 概述 LLBLGen是一个数据访问的解决方案; 你使用LLBLGen创建实体/域模型,定义了映射和 ...

  10. error: /usr/include/objc/objc-class.h: No such file or directory

    When i use the example of ShareKit package,i have come across this error:"error: /usr/include/o ...