9.如何实现大正整数相加
题目
给出两个很大的整数,要求实现程序求出两个整数之和。超出Java中的Long类型的范围的整数,如何求和。
思路
使用到小学的数学了,对于大的数,小学老师会教,列竖式进行计算。
对于,计算机,无法计算太大的数,进行加运算。我们可以将大的数,转成一个个小的整数,创建两个int[],长度是较大整数的位数+1。大整数一般是使用字符串进行存储的,倒序转化到两个整数数组中,倒叙是为了,满足习惯的顺序遍历数组。然后按位相加,记录结果到,多一位的数组中,多出来的哪一位就是为了给可能出现的进位,预留的位置。然后,再顺序凭借为字符串,作为结果。
代码
public static String bigNumberSum(String bigNumA, String bigNumB) {
int maxLen = Math.max(bigNumA.length(), bigNumB.length());
int[] arrayA = bigNumberToIntArray(bigNumA, maxLen + 1);
int[] arrayB = bigNumberToIntArray(bigNumB, maxLen + 1);
int[] result = new int[maxLen + 1];
//遍历数组按位相加
for (int i = 0; i < result.length; i++) {
int temp = result[i];
temp += arrayA[i];
temp += arrayB[i];
//如果需要进位
if (temp >= 10) {
temp = temp - 10;//计算进位后的值,保存到当前位
//将高于当前位的直接设为1,为什么不是+1,因为此时的result[i+1]的值一定是0,赋值1和+1结果一样,
//但是对于计算机的底层指令,赋值操作指令会少一些,因为+1操作,要先从寄存器中读取值,再+1,再会写到寄存器,而赋值操作,不需要读取,直接赋值
result[i + 1] = 1;
}
result[i] = temp;//保存到当前位
}
StringBuffer sb = new StringBuffer();
boolean findFirst = false;
for (int i = result.length - 1; i >= 0; i--) {
if(!findFirst){
if(result[i] == 0){//如果最后一位为0,则不将这个0添加到最后结果中
continue;
}
findFirst = true;//除最后一位都不再进入该if语句
}
sb.append(result[i]);//其余位都添加
}
return sb.toString();
}
/**
* @param bigNumber 被转换的大数
* @param arrayLength 转换后的intArray的长度
* @return 例 "123456789" 10 -> {9,8,7,6,5,4,3,2,1,0}
*/
public static int[] bigNumberToIntArray(String bigNumber, int arrayLength) {
int[] arr = new int[arrayLength];
int len = bigNumber.length();
for (int i = 0; i < len; i++) {
//倒序获取字符的数字值,顺序存到arr中
arr[i] = bigNumber.charAt(len - i - 1) - '0';
}
return arr;//未赋值的,默认值为0
}
public static void main(String[] args) {
System.out.println(bigNumberSum("123456789","123456789"));
}
时间复杂度为O(n)。
上述代码可以,进行优化,因为差分的数组,可以大一些,因为java中,int类型的取值范围是(-2147483648-2147483647),最多可以有10位,给溢出位留一位,取大整数,每9位做一个int[]数组的元素,进行加法运算(也可以使用long类型数组,只是扩展一个思路)。
只是为了记录自己的学习历程,且本人水平有限,不对之处,请指正。