高精度乘法
输入格式
两行,两个整数。
输出格式
一行一个整数表示乘积。
思路
- 其实高精度乘法的思路就是模拟正常的乘法
- 我们使用一个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;
}
}