大数问题:大数加法 与 大数乘法 最简单大数乘法
大数加法很简单,大叔乘法只是以大数加法为基础的,光从难度来说,两者差不多。
思路:这里没有借鉴别人牛逼的算法,现在也没有这个需求,就用最通俗的思路自己想了一个。
先举一个简单的例子
所以乘法就是每一位个位数相乘再乘以多少次方就可以了,这个多少次就是两者的数组位置的索引相加。
看看关键代码
for (int i = 0; i < aLen; i ++) { for (int j = 0; j < bLen; j ++) { int[] c = new int[length]; //先给后面的0补补好 int height = (aLen - i - 1) + (bLen - j - 1);// 5 3 int sum = a[i] * b[j]; if (sum >= 10) { c[length - height - 1] = sum % 10; c[length - height - 2] = (sum - sum % 10) / 10; } else { c[length - height - 1] = sum; } result = plus(result, c); } }height就是次方,sum就是个位数相乘,我们只需要弄一个新的数组存放,只需要把sum移动height个位置,我们这个数就出来了。
至于这个plus就是把我们的结果数组和这一次的出来的数组相加就可以了,加完了就得出最终结果了。
上全部代码
public class BigNumberMultiDiv { //(a*10+b) * (c*10+d) = (a*c)*100 + (a*d+c*b)*10 + b*d int[] a; int[] b; BigNumberMultiDiv() { //先存放两个数据试试 a = new int[6];//679 a[0] = 6; a[1] = 7; a[2] = 9; a[3] = 8; a[4] = 8; a[5] = 8; b = new int[4];//8315 b[0] = 8; b[1] = 3; b[2] = 1; b[3] = 5; //test1:600000 * 8000 = 4800000000 int[] c = multi(a, b); for (int i = 0; i < c.length; i ++) { System.out.print(c[i] + " "); } } //大数加法 目前只考虑了正数 int[] plus(int[] a, int[] b) { int aLen = a.length; int bLen = b.length; int maxLen = Math.max(aLen,bLen); int cLen = maxLen + 1;//由ab长度得出c长度,考虑到进位 int c[] = new int[cLen];//注意一开始是倒序的 int flag = 0; if (aLen == bLen) { for (int i = aLen - 1, j = 0; i >= 0; i --, j ++) { int num = a[i] + b[i] + flag; flag = 0; if (num >= 10) { num -= 10; flag = 1; } c[j] = num; } if (flag == 1) { c[cLen - 1] = 1; } } else { int minLen = Math.min(aLen, bLen); int k = 0;//这里指代c数组的index //加他们共有的部分 for (int i = aLen - 1, j = bLen -1; i > aLen - 1 - minLen; i --, j --) { int num = a[i] + b[j] + flag; flag = 0; if (num >= 10) { num -= 10; flag = 1; } c[k] = num; k++; } //不公有的部分 for (int i = maxLen - minLen - 1; i >= 0; i --) { int num = aLen > bLen ? a[i] + flag : b[i] + flag; flag = 0; if (num >= 10) { num -= 10; flag = 1; } c[k] = num; k ++; } if (flag == 1) { c[cLen - 1] = 1; } } //倒序回来 //真实位数 int realLen = cLen; //代表没进位 if (flag == 0) { realLen = cLen - 1; } int temp; int d[] = new int[realLen]; for (int i = 0, j = realLen - 1; i < realLen; i ++, j --) { d[i] = c[j]; } return d; } //大数乘法 int[] multi(int[] a, int[] b) { //乘法可以乘出来的位数 a位数组 * b位数组 最小 a + b - 1位 最大 a + b位 int aLen = a.length; int bLen = b.length; int length = aLen + bLen; int[] result = new int[length]; //思路 两个for循环 结果等于每个数之间相乘并且乘以10的(i + j)次,得出这么多结果,累加 for (int i = 0; i < aLen; i ++) { for (int j = 0; j < bLen; j ++) { int[] c = new int[length]; //先给后面的0补补好 int height = (aLen - i - 1) + (bLen - j - 1);// 5 3 int sum = a[i] * b[j]; if (sum >= 10) { c[length - height - 1] = sum % 10; c[length - height - 2] = (sum - sum % 10) / 10; } else { c[length - height - 1] = sum; } result = plus(result, c); } } return result; } public static void main(final String[] args) throws Exception { BigNumberMultiDiv bigNumberMultiDiv = new BigNumberMultiDiv(); } }