您的位置:首页 > 其它

大整数相乘 分治法

2015-10-27 00:33 232 查看
package 大整数相乘分治;

import java.math.BigInteger;
import java.util.Scanner;

public class Main {
static int BitCount(BigInteger x){
int i=x.toString(2).length();
return i;
}
static BigInteger multiply_me(BigInteger x,BigInteger y){
int n_bitcount;
BigInteger x_l, x_r, y_l, y_r;
BigInteger p1, p2, p3;
if (BitCount(x) > BitCount(y))n_bitcount = BitCount(y);
else n_bitcount = BitCount(x);
if (n_bitcount == 1 || n_bitcount == 0) {
return x.multiply(y);
}
else{
//x y切割成两部分 分为左半部分和右半部分
x_l =x.shiftRight(n_bitcount/2);
x_r=x.subtract(x_l.shiftLeft(n_bitcount/2));
y_l=y.shiftRight(n_bitcount/2);
y_r=y.subtract(y_l.shiftLeft(n_bitcount/2));
//计算p1 p2 p3的值
p1 = multiply_me(x_l,y_l);
p2 = multiply_me(x_r,y_r);
p3=multiply_me(x_l.add(x_r),y_l.add(y_r));
//由于2^n可能会很大所以需要用BigInteger来保存
//当时提交OJ的时候就是因为把2^n的值当int处理了所以WA
//初始化_2n _2n_half 为1通过移位得到2^n 2^(n/2)
BigInteger _2n=new BigInteger("1");
BigInteger _2n_half=new BigInteger("1");
_2n=_2n.shiftLeft((n_bitcount/2)*2);
_2n_half=_2n_half.shiftLeft(n_bitcount/2);
//format1=p1*2^n
BigInteger format1=p1.multiply(_2n);
//format2=(p3-p2-p1)*2^(n/2)
BigInteger format2=p3.subtract(p1).subtract(p2).multiply(_2n_half);
BigInteger format3=p2;
BigInteger format_sum=format1.add(format2).add(format3);
//返回  p1*2^n+(p3-p2-p1)*2^(n/2)+p2  大整数分治
return format_sum;
}

}
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
String x_s=new String();
String y_s=new String();
while(scan.hasNext()){
x_s=scan.next();
y_s=scan.next();
BigInteger x=new BigInteger(x_s);
BigInteger y=new BigInteger(y_s);
System.out.println(multiply_me(x,y));
}
}
}
最近学完了分治法 也该到OJ上找虐了 在做大整数相乘的时候卡住了 卡了三四天才弄出来

这道题就是利用高斯乘法的优化把四次乘法化简为三次 从三次减少到四次似乎没多大效果但多次递归叠加的效果就明显了

这次还是因为没把书本看清楚算法描述过程弄透彻并进行细心检验 导致对书本内容的理解错误而浪费很多时间

写代码之前一定要先在纸上写写画画什么的 确保对算法过程已经清楚了

确保思路清晰再写代码

确保思路清晰再写代

当过程清晰了 这道题也就完成了90%了 代码只是思路的计算机语言表达形式而已 重要的部分还是自己对问题的清晰的思路
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: