美文网首页
大数相乘——java版

大数相乘——java版

作者: 耳_总 | 来源:发表于2016-11-02 16:37 被阅读364次

之前面试的时候被问到两个很大很大的数相乘在java中怎么把它算出来,显然不能直接相乘,当时我只回答出来了用BigInteger,然而不是最好的答案。大数相乘的核心思想是将数字转化为字符串,然后逐位相乘转化最后才得出结果。
先上一段代码:

public static void main(String[] args) {
        String str1 = "23451515412151511212";
        String str2 = "3614844151515151515151";
        
        int len1 = str1.length();
        int len2 = str2.length();
        
        char[] s1 = str1.toCharArray();
        char[] s2 = str2.toCharArray();
        convert(s1,len1);//高低位对调
        convert(s2,len2);
        int csize = len1+len2+3;
        //创建一个数组,处理相乘后的结果,两个数相乘之后的结果的位数不超过两个数的位数的和加3
        //比如两个两位数相乘是定小于100*100的
        int c[] = new int[csize];
        // 乘积数组填充0  
        for (int ii = 0; ii < csize; ii++) {  
            c[ii] = 0;  
        } 
        for(int i=0;i<len1;i++) {
            for(int j=0;j<len2;j++) {
                int a = Integer.parseInt(String.valueOf(s1[i]));
                int b = Integer.parseInt(String.valueOf(s2[j]));
                c[i+j] += a* b; 
            }
        }
public static void convert(char[] s,int len) {
        
        for(int i=0;i<len/2;i++) {
            s[i] += s[len-i-1];
            s[len-i-1] = (char) (s[i]-s[len-i-1]);
            s[i] = (char) (s[i] - s[len-i-1]);
        }
    }

先看convert方法,这里高低位对调的目的是将各位放在数组的最前面,方便数组下标进行操作,当然也可不用这么干,看个人。其他的代码没难度,最核心的思想在这里:

for(int i=0;i<len1;i++) {
            for(int j=0;j<len2;j++) {
                int a = Integer.parseInt(String.valueOf(s1[i]));
                int b = Integer.parseInt(String.valueOf(s2[j]));
                c[i+j] += a* b; 
            }
        }

解释下:这里是将两个数组循环遍历,个位数的数字相乘。为什么可以这么做呢?举个列子:
假设有两个数
A=863
B=974
那么乘积的个位不用说为3x4的个位得来,即12%10=2,想高位进1;
十位数:先看看将两个数的十位相乘7x6=42,后面再加两个0,即4200,这样不可能得出一个数的乘机的十位,一个数的十位那么一定是十位和个位的乘积:6x4+7x3 = 45,加个0为450,即十位是5,百位进4。
转为数组、反序后:

01.png

就有C[i+j] += A[i]*B[j];这里的下标运用的很巧妙。相当于10^n,从而来表示数字的位数。
余下的代码:

//高位处理
        int m = 0;
        for(;m<csize;m++) {
            int carry = c[m]/10;
            c[m] = (char) (c[m]%10);
            if(carry>0) {
                c[m+1] += (char) carry;
            }
        }
        
         // 找到最高位  
        for (m = csize - 1; m >= 0;m--) {  
            if (c[m] > 0)  
                break;  
        } 
        
        // 由最高位开始打印乘积  
        for (int n = 0; n <= m; n++) {  
            System.out.print(c[m - n]);  
        }  
        System.out.println("");  

结果:84773573331783328327666000249636164373012

相关文章

  • 大数相乘——java版

    之前面试的时候被问到两个很大很大的数相乘在java中怎么把它算出来,显然不能直接相乘,当时我只回答出来了用BigI...

  • 大数相乘、大数相加、大数相减(Java版)

    大数相乘 假设有A和B两个大数,位数分别为a和b。根据我们平常手动计算乘法的方式可以看出,最终的结果的位数c一定小...

  • 大数相乘--golang简单实现

    大数乘法之golang实现所谓大数相乘(Multiplication algorithm),就是指数字比较大,相乘...

  • 大数相乘

    所谓大数相乘(Multiplication algorithm),就是指数字比较大,相乘的结果超出了基本类型的表示...

  • 大数相乘

  • 大数相乘

    两个大数相乘,这两个大数分别是a和b,现在分割成两部分,每一部分都是N位,假设是10进制的,其实对于2进制也同样适...

  • 大数相乘

  • 大数相乘

    别忘了把字符串反转便于求导,还有去除前面的0的时候别忘了结果本来就为0的情况,两个数相乘最长长度为len1+len2。

  • 大数相乘

    给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示...

  • 2018-07-18

    大数据学习路线(完整细节版) 大数据学习路线 java (Java se,javaweb) Linux(shell...

网友评论

      本文标题:大数相乘——java版

      本文链接:https://www.haomeiwen.com/subject/tdwvuttx.html