题目
给出两个很大的整数,如何求出他们的和?
解读:
题目很简单,但是内涵不太好说,很大,,,我们就直接考虑那种“连long类型都装不下的整数”的情况了。
回想一下,我们读小学的时候,老师教我们加法运算,要“ 列竖式 ”:
4 3 2 5 4 6 4
加 9 3 4 1 2 4
——————
5 2 5 9 5 8 8
那么,我们为什么要列竖式呢?
——对于这么大的数,显然我们无法一步得到结果!
计算机也是如此。。。
但是,这么大的数,如何存储? —— 数组 !数组的每一个元素,对应着大整数的每一个位数。
步骤
1.创建两个整形数组,数组长度是 较大整数位数+1 。把每一个整数 倒序 “放入”数组中(最高位存于数组的尾部)。
2.创建结果数组,其长度仍然是 较大整数位数+1 。
3.遍历,从左向右依次对应下标相加两个数组元素。如果大于10,减去,存1(利用临时变量)。
进的1在进行下一位前直接存入下一位(初值)。
说明:
为什么长度设为“较大整数位数+1”? ——为最高位可能的进位预留
为什么“最高位存于数组的尾部”? ——这样符合从左往右访问数组的习惯
代码展示(java版):
package 数据结构;
/**
* 数组实现:大整数求和
*/
public class DZSQH {
public static String bigNumberSum(String bigNumberA,String bigNumberB){
int maxLength=bigNumberA.length()>bigNumberB.length()?bigNumberA.length():bigNumberB.length();
int[] arrayA=new int[maxLength+1];
// 逆序存储
for(int i=0;i<bigNumberA.length();i++){
arrayA[i]=bigNumberA.charAt(bigNumberA.length()-i-1)-'0';
}
int[] arrayB=new int[maxLength+1];
for(int i=0;i<bigNumberB.length();i++){
arrayB[i]=bigNumberB.charAt(bigNumberB.length()-i-1)-'0';
}
int[] result=new int[maxLength+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;
result[i+1]=1;
}
result[i]=temp;
}
// 把result数组再次逆序并转为String
StringBuilder sb=new StringBuilder();
boolean findFirst=false;
for(int i=result.length-1;i>=0;i--){
if(!findFirst){
if(result[i]==0){
continue;
}
findFirst=true;
}
sb.append(result[i]);
}
return sb.toString();
}
}
第32-38行作用是什么呢?
因为开始时我们说“为最高位预留一位”,那么,这一位到底被使用没有?在这里判断一下,否则逆序后就会发生“ 首位为0 ”的尴尬情况。
放个数试一下:
public static void main(String[] args){
System.out.println(bigNumberSum("43214134134","12312143431412"));
}
其时间复杂度被控制在O(n)!
链表实现相比数组更简便一点,但是相对也难理解一些:
每日一算–大数相加