一、 题目描述
二 、解题思路
这题不能转成整数再相,因为数据范围太大了,会发生溢出
- 解释
num.length可以到 10^4,也就是说num可以表示一个一万位的整数。这个数远远超出long long(约 19 位十进制数)的表示范围。
故必须用模拟竖式加法的方式,逐位处理。 - 核心考点
大整数加法的数组模拟
三、代码
/** * Note: The returned array must be malloced, assume caller calls free(). */int*addToArrayForm(int*num,intnumSize,intk,int*returnSize){intk1=k;intlen=0;intret=0;intadd=0;//表示进位intaSize=numSize-1;intkSize=0;// 1. 计算 k 的位数while(k1>0){k1/=10;len++;}// 2. 取 numSize, k的位数 的最大值 作为循环次数if(numSize>len){len=numSize;}// 3. 申请结果空间,多 1 位用于最高位进位int*tmp=(int*)malloc(sizeof(int)*(len+1));// 4. 从低位到高位逐位相加while(len--){inta=0;// 取出 num 当前位if(aSize>=0){a=num[aSize];aSize--;}// 当前位相加:num位 + k最低位 + 进位ret=a+k%10+add;k/=10;// 处理进位if(ret>=10){ret-=10;add=1;}else{add=0;}// 先存低位,最后再反转tmp[kSize]=ret;kSize++;}// 5. 最高位还有进位,补 1if(add==1){tmp[kSize]=1;kSize++;}// 6. 反转数组for(intleft=0,right=kSize-1;left<=right;left++,right--){intt=tmp[left];tmp[left]=tmp[right];tmp[right]=t;}*returnSize=kSize;returntmp;}四、解释代码
1.取最长位数
if(numSize>len){len=numSize;}它决定了循环次数,加法必须从最低位加到最高位。如果两个加数长度不同,那么循环次数必须至少等于较长的那个数的位数,否则高位会被漏掉。
2.分配结果空间
int*tmp=(int*)malloc(sizeof(int)*(len+1));两个数相加,结果最多比最长的加数多一位,所以是len+1。
3.处理[1,2]+1234这种情况
inta=0;if(aSize>=0){a=num[aSize];aSize--;}因为aSize的长度比k小,所以后面aSize–之后会变成负,把aSize为负数的部分规定都为0。
4.处理最高位进位
if(add==1){tmp[kSize]=1;kSize++;}最高位进位只可能是1