java笔试题:高精度乘法

高精度乘法

输入格式
两行,两个整数。

输出格式
一行一个整数表示乘积。

思路

  • 其实高精度乘法的思路就是模拟正常的乘法
  • 我们使用一个data二维矩阵存储乘法的中间结果
  • 最后对data进行按列相加

举例说明

我们现在有两个乘数1234和95

int[] num1 = new int[]{1,2,3,4};
int[] num2 = new int[]{9,5};

乘法需要将一个数放在上面,一个数放在下面。手算如下:我们默认将num2放在下面。
在这里插入图片描述
可以发现中间的计算结果就是一个二维矩阵

此时我们需要定义如下变量:

  • data【】【】矩阵存储中间的计算结果,要提前计算data的行和列。
  • res【】存储最后的结果

由于我们将num2放在下面,所以data的行数就等于num2的长度。再仔细观察发现,data的列数应该 = num1.length + num2.length (这是已经考虑进位的结果)

其次res【】的长度要比data的列数多1,因为最前面可能会进位

int[][] data = new int[num2.length][num1.length + num2.length];//模拟乘法的矩阵
int[] res = new int[data[0].length+1];//位数永远会多一位 因为最前面可能进位

这时候我们就要分别将num1去乘以num2的每一位(从个位开始),每次都会得到一个数(数组形式)。

这里pre是用来记录当前每一行的最后一个数要从哪里开始存。因为我们知道只有第一行的最后一个数是存在末尾的。

int prex = data[0].length-1;//data矩阵中每一行最后一个数从哪开始存储
for(int i = num2.length - 1, j = 0; i >= 0; i--, j++){
      data[j] = cacaulate(num1,num2[i],prex--,data[0].length); //计算num1 分别乘以 num2中的每一位 存储到data矩阵中
}

public static int[] cacaulate(int[] nums1, int n, int prex, int length){
            int[] res = new int[length];
            int flag = 0;
            for(int i = nums1.length-1, j = prex;  i >= 0; i--){
                int temp = nums1[i] * n + flag;
                res[j--] = temp % 10;
                flag = temp / 10;
                if(i == 0){
                    res[j] = flag;
                    break;
                }
            }
            return  res;
        }

在计算之后我们会得到如下的data二维数组

在这里插入图片描述

此时我们只需要按列将这个二维数组相加就好了

//开始最后的加法
            int flag = 0; //进位
            for(int j = data[0].length-1, index = data[0].length; j >= 0; j-- ){
                int temp  = flag;
                for(int i = 0; i < data.length; i++){
                    temp += data[i][j];
                }
                res[index--] = temp % 10;
                flag = temp / 10;

                if(j == 0) {//如果加到最后一位了,则需要最前面一位进位
                    res[index] = flag;
                    break;
                }
            }

最终结果需要把前面的0去掉

完整代码如下:

public class test18 {

        public static void main(String[] args) {

            int[] num1 = new int[]{1,2,3,4};
            int[] num2 = new int[]{9,5}; //乘法 num2放在下面乘


            int[][] data = new int[num2.length][num1.length + num2.length];//模拟乘法的矩阵
            int[] res = new int[data[0].length+1];//位数永远会多一位 因为最前面可能进位

            int prex = data[0].length-1;//data矩阵中每一行最后一个数从哪开始存储
            for(int i = num2.length - 1, j = 0; i >= 0; i--, j++){
                data[j] = cacaulate(num1,num2[i],prex--,data[0].length); //计算num1 分别乘以 num2中的每一位 存储到data矩阵中
            }


            //开始最后的加法
            int flag = 0; //进位
            for(int j = data[0].length-1, index = data[0].length; j >= 0; j-- ){
                int temp  = flag;
                for(int i = 0; i < data.length; i++){
                    temp += data[i][j];
                }
                res[index--] = temp % 10;
                flag = temp / 10;

                if(j == 0) {//如果加到最后一位了,则需要最前面一位进位
                    res[index] = flag;
                    break;
                }
            }



            //把前面的零去掉
            int i = 0;
            while(res[i++] != 0) ;
            for(int j = i; j < res.length; j++){
                System.out.print(res[j]);
            }





        }

        public static int[] cacaulate(int[] nums1, int n, int prex, int length){
            int[] res = new int[length];
            int flag = 0;
            for(int i = nums1.length-1, j = prex;  i >= 0; i--){
                int temp = nums1[i] * n + flag;
                res[j--] = temp % 10;
                flag = temp / 10;
                if(i == 0){
                    res[j] = flag;
                    break;
                }
            }
            return  res;
        }
}
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值