分治法求两个大整数相乘(分三段,5次相乘)

import java.awt.*;
import java.math.*;
import java.util.Scanner;
public class homework {
    public static void main(String[] args){
        //输入两个大整数
        String strNumA=new Scanner(System.in).nextLine();
        String strNumB=new Scanner(System.in).nextLine();
        
        //获取字符串的长度
        int len=strNumA.length();
        //分三份
        int len_3=(int)Math.floor(len/3);

        long numA_0=huaFen(strNumA,len-len_3,len);//A
        long numA_1=huaFen(strNumA,len-2*len_3,len-len_3);//B
        long numA_2=huaFen(strNumA,0,len-2*len_3);//C

        long numB_0=huaFen(strNumB,len-len_3,len);//D
        long numB_1=huaFen(strNumB,len-2*len_3,len-len_3);//E
        long numB_2=huaFen(strNumB,0,len-2*len_3);//F

        //构造  减少乘法的次数
        long M_1=numA_0*numB_0;
        long M_2=numA_2*numB_2;
        long M_3=(numA_0+numA_1+numA_2)*(numB_0+numB_1+numB_2);
        long M_4=(numA_0-numA_1+numA_2)*(numB_0-numB_1+numB_2);
        long M_5=(numA_0-2*numA_1+4*numA_2)*(numB_0-2*numB_1+4*numB_2);

        //系数  10 n-1
        long X_1=M_1;//0
        long X_2=( 3*M_1 -12*M_2 + 2*M_3 -6*M_4+M_5)/6;//1
        long X_3=(M_3+M_4)/2-M_1-M_2;//2
        long X_4=( -3*M_1+ 12*M_2 +M_3+ 3*M_4-M_5)/6;//3
        long X_5=M_2; //4

        System.out.println(strSum(X_1,X_2,X_3,X_4,X_5,len_3));
    }

    //字符串转为数字
    public static long  stringToNum(String str){
        return Long.valueOf(str);
    }

    public static long huaFen(String str,int start,int end){
        return stringToNum(str.substring(start,end));
    }

    public static StringBuilder numToString(long num,int len_3){
        String str=String.valueOf(num);
        StringBuilder strbuilder=new StringBuilder(str);

        for (int i = 0; i < len_3; i++) {//尾部加0
            strbuilder.append("0");
        }

        return  strbuilder;
    }

    public static StringBuilder addSum(StringBuilder s1,StringBuilder s2){
        StringBuilder res = new StringBuilder();

        s1=s1.reverse();
        s2=s2.reverse();
        int len1 = s1.length();
        int len2 = s2.length();
        int len;

        if (len1 < len2) {
            len = len2;
            int count = len2 - len1;
            while (count-- > 0)
                s1.append('0');
        } else {
            len = len1;
            int count = len1 - len2;
            while (count-- > 0)
                s2.append('0');
        }

        int overflow = 0;
        int num;

        for (int i = 0; i < len; i++) {
            num = s1.charAt(i) - '0' + s2.charAt(i) - '0' + overflow;
            if (num >= 10) {
                overflow = 1;
                num -= 10;
            } else {
                overflow = 0;
            }
            res.append(String.valueOf(num));
        }

        if (overflow == 1)
            res.append(1);
        return res.reverse();
    }

    public static String strSum(long m1,long m2,long m3,long m4,long m5,int len_3){

        StringBuilder str_1=numToString(m1,0);
        StringBuilder str_2=numToString(m2,len_3);
        StringBuilder str_3=numToString(m3,2*len_3);
        StringBuilder str_4=numToString(m4,3*len_3);
        StringBuilder str_5=numToString(m5,4*len_3);


        return addSum(str_5,addSum(str_4,addSum(str_3,addSum(str_1,str_2)))).toString();

    }
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值