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

大数相乘

发布时间:2020-12-14 02:45:24 所属栏目:大数据 来源:网络整理
导读:大数相乘 大整数乘法,就是乘法的两个乘数比较大,最后结果超过了整形甚至长整形的最大范围,此时如果需要得到精确地结果,常规的乘法就不能得到正确的结果了。此时需要算法思想了,对,就是分治算法,将乘数“分割“,将大整数计算转换为小整数计算。 咱先

大数相乘

大整数乘法,就是乘法的两个乘数比较大,最后结果超过了整形甚至长整形的最大范围,此时如果需要得到精确地结果,常规的乘法就不能得到正确的结果了。此时需要算法思想了,对,就是分治算法,将乘数“分割“,将大整数计算转换为小整数计算。

咱先来个小点的数乘法,然后逐步找出大数乘法的解法:

1、 一位乘法就是乘法口诀,没什么可说的。

2、 说说2位乘法??? 12*23 = 408 分割成一位乘法,满1位也就是到10就进位

1??????2

? ?X ?3?? 4

????? 4?? 8

??3?? 6???

? 4?? 0?? 81

? 接下来就是找规律,1*3(1*4+2*3)2*4 = 3(10)8,可以发现,括号中的10已满10,需要进1,而3加1,正好为4,所以最后结果为:408;

换句话说AB*CD = AC(AD + BC)BD . 注意括号两边是拼接起来,不是相乘

3、 接下来验证4位乘法

1??????2? 3? 4

? 5? 6?7? 8

?????? 9?? 8?7? 2

???? 8? 6?3? 8

? 7? 4?0? 4

6? 1? 7? 0??????????

7? 0? 0?6? 6? 5? 2

?

A=12,B=34,C=56,D=78?????

AC(AD + BC)BD

AC = 672,AD + BC = 2840,BD = 2652

4位分割后变成2位数乘法,所以满2位需要进位,也就是到100就进位。

从低位开始BD满两位进位,低位为52,进位26,? 2840+26=2866, 2866剩下66需要进位28, 672+28=700.? 所以最终结果拼接起来就是7006652

?

规律出来了AB*CD =AC(AD + BC)BD

接下来就是利用分治思想,利用递归算法进行计算实现、

大致思路分为如下:

a、 如果两个整数的位数小于等于4位,可以计算出结果

b、 如果X、Y两个数位数不用,以最长的为准,短的前面补0,使位数相同都为n

c、? 将大数X、Y分割为位数是n/2的数,分别为A、B、C、D

d、 将A、B、C、D递归调用第一步,直到分割为可以计算的4位数,从而得到结果

(高位)AC,(中位)AD,(中位)BC,(低位)BD

e、 判断BD是否有进位bd,保留位为BD’,?如果有则AD+BC+bd为中位abcd,判断abcd是否有进位abcd‘、保留位是ABCD’,如果有则高位为AC+abcd’.

f、?? 最后将结果拼接起来就是AC+abcd’+ABCD’+BD’。

?? 下面附上Java代码:

?

import java.io.BufferedInputStream;

import java.util.Scanner;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

?

public classMain {

?

??? public static void main(String[] args) {

?

??????? // 正则表达式:不以0开头的数字串

??????? Stringpat = "^[1-9]d*$";

??????? Patternp = Pattern.compile(pat);

?

??????? System.out.println("请输入大数A(不以0开头的正整数)");

??????? Scannerscanner = newScanner(newBufferedInputStream(System.in));

??????? StringA = scanner.nextLine();

??????? Matcherm = p.matcher(A);

??????? if (!m.matches()) {

??????????? System.out.println("输入不合法");

??????????? return;

??????? }

?

??????? System.out.println("请输入大数B(不以0开头的正整数)");

??????? scanner= newScanner(newBufferedInputStream(System.in));

??????? StringB = scanner.nextLine();

??????? m= p.matcher(B);

??????? if (!m.matches()) {

??????????? System.out.println("输入不合法");

??????????? return;

??????? }

?

??????? System.out.println(A + "*" + B + "="

??????????????? +bigIntMultiply(A,B,Math.max(A.length(),B.length())));

?

??? }

?

??? /**

??? ?* @param A

??? ?*???????????大数A

??? ?* @param B

??? ?*???????????大数B

??? ?* @param len

??? ?*???????????要保证lenA,B长度的最大值

??? ?* @return最终相乘结果

??? ?*/

??? private static StringbigIntMultiply(String X,String Y,int len) {

?

??????? // 最终返回结果

??????? String str = "";

???????

??????? // 保证A,B长度为最长一个的长度,短的前面补0

??????? X= formateNumber(X,len);

??????? Y= formateNumber(Y,len);

?

??????? // 如果长度小于4位,直接计算

??????? if (len <= 4) {

??????????? return "" + (Integer.parseInt(X)* Integer.parseInt(Y));

??????? }

?

??????? // 分割X,Y

??????? int len1 = len / 2;

??????? int len2 = len - len1;

??????? StringA = X.substring(0,len1);

??????? StringB = X.substring(len1);

??????? StringC = Y.substring(0,len1);

??????? StringD = Y.substring(len1);

?

??????? // 递归,逐步分割

??????? int lenM = Math.max(len1,len2);

??????? StringAC = bigIntMultiply(A,C,len1);

??????? StringAD = bigIntMultiply(A,D,lenM);

??????? StringBC = bigIntMultiply(B,lenM);

??????? StringBD = bigIntMultiply(B,len2);

?

??????? // AC(AD+BC)BD公式

??????? // 先看BD结果,以及是否有进位,用String[0]数组保存原位,String[1]保存进位

??????? StringsBD[] = dealString(BD,len2);

?

??????? // 计算(AD+BC)的结果

??????? StringADBC = addition(AD,BC);

????????

??????? //AD+BC)加上BD的进位

??????? if (!"0".equals(sBD[1])){

??????????? ADBC= addition(ADBC,sBD[1]);

??????? }

???????

??????? // 得到ADBC的进位

??????? String[] sADBC = dealString(ADBC,lenM);

?

??????? // AC加上ADBC的进位

??????? AC = addition(AC,sADBC[1]);

?

??????? // 最终结果

??????? str = AC + sADBC[0] + sBD[0];

?

??????? return str;

??? }

?

??? private static String addition(Stringad,String bc) {

??????? Stringstr = "";

??????? // 两个字符串长度要相同

??????? int lenM = Math.max(ad.length(),bc.length());

??????? ad= formateNumber(ad,lenM);

??????? bc= formateNumber(bc,lenM);

?

??????? // 安位加,进位保存在flag

??????? int flag = 0;

?

??????? for (int i = lenM - 1; i >=0; i--) {

??????????? int t = flag + Integer.parseInt(ad.substring(i,i + 1))

?????????????????? +Integer.parseInt(bc.substring(i,i + 1));

?

??????????? if (t > 9) {

??????????????? flag= 1;

??????????????? t= t - 10;

??????????? }else{

??????????????? flag= 0;

??????????? }

?

??????????? str= str + t + "";

??????? }

?

??????? if (flag != 0) {

??????????? str= ""+ flag + str;

??????? }

??????? return str;

??? }

?

??? private static String[]dealString(String ac,int len) {

??????? // 默认不进位,str[1]进位上面赋值为0

??????? Stringstr[] = { ac,"0"};

?

??????? if (ac.length() <= len){

??????????? ac= formateNumber(ac,len);

??????????? str[0]= ac;

??????? }else{

??????????? int lenPre = ac.length() -len;

??????????? str[0]= ac.substring(lenPre);

??????????? str[1]= ac.substring(0,lenPre);

??????? }

?

??????? return str;

??? }

?

??? private static StringformateNumber(String x,int len) {

??????? while (x.length() < len) {

??????????? x= "0"+ x;

??????? }

??????? return x;

??? }

?

}

(编辑:李大同)

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

    推荐文章
      热点阅读