一、题目简述
给定一个数组和整数,进行相加保存到数组中。
例如:
num=[1,2,0,0]代表1200
k=15
相加后 newnum=[1,2,1,5]
二、题目分析
如果将num数组化为整数,那么将有可能出现超出int范围的情况;所以采用将整数k进行拆分,与数组每一位对应相加的方法。
所以可以采用malloc一个新的数组(Array)来进行储存,但数组的长度如何来确定?
很显然,两个整数相加,最总结果只会等于最长整数位数或者比最长整数位数多一位。那么我们可以计算出k的位数,num的长度,比较它们取最大lenth,开辟lenth+1的数组长度,来保证Array能够保存所有位数。
但是我们并不知道相加完的两个数到底是lenth位数,还是lenth+1的位数,在将数存进Array中时,我们如果从后向前存储,便无法确定最后的位置。
例如:
num=[9, 9 ,5]
k=58;
num+k=995+58=1053;
Array=[1,0,5,3]
但是在两数相加完成前,我们并不知道Array是从2下标位置开始存,还是3下标位置。所有我们可以采用倒着存储的方式。
Array=[3,5,0,1]
这样只需在结束后逆置一下数组即可。
三、代码分析
while(tmp)
{
tmp/=10;
Ksize++;//计算数字k的位数
}
int lenth=(numSize>Ksize)?(numSize):(Ksize);
int* Array=(int*)malloc(sizeof(int)*(lenth+1));//开辟一个新的数组
1、开辟新数组
计算k的位数,将最大值赋给lenth。malloc一个新数组Array,长度为lenth+1。
int Arraypos=0;//num数组开始位置
int numpos=numSize-1;//num数组末尾位置
int carry=0;//进位标志
while(lenth--)
{
int a;
if(numpos<0)
a=0;//数组长度比k位数小
else
a=num[numpos];
Array[Arraypos]=k%10+a+carry;//将每一位的数逆序存入新数组
k/=10;
if(Array[Arraypos]>9)
{
Array[Arraypos]-=10;
carry=1;
}
else
carry=0;
Arraypos++;
numpos--;
}
2、判断是否越界
Arraypos是Array的下标位置,开始为0;numpos为数组num开始位置,开始为numSize-1(num数组末尾)。a用来保存num[numpos]的值;carry表示是否进位,开始置为0,表示无进位。
在相加之前,要对numpos的位置进行判断,因为会出现num长度小于k位数的情况,那么在进行相加,numpos就会越界。
例如:
当加法还没有完成时,numpos已经走到0的位置,执行numpos–后便会造成越界访问。所有对numpos的值进行一个判断:numpos小于0时a置零即可。
if(numpos<0)
a=0;//数组长度比k位数小
else
a=num[numpos];
3、按位相加,保存到Array
将num的每一项与k每一位相加,执行:Array[Arraypos]=k%10+a+carry。
保存到Array[Arraypos]中。
对Array[Arraypos]进行判断,若Array[Arraypos]>9则说明需要进位,carry置为1;否则carry置为0。
直到所有位数相加完成,循环结束。
4、处理最后一位
若num=[1,2,0,0]
k=15
那么Array=[5,1,2,1,],Arraypos的值则为数组长度。
若num=[9,9,5]
k=58
在相加结束后
Array=[3,5,0, ],carry=1
说明仍有一位进位未处理,若carry=1,将Array[Arraypos]置1,Arrypos++即可。
if(carry==1)//循环结束carry仍为1,还有一个进位未处理
{
Array[Arraypos]=1;
Arraypos++;
}
5、逆置数组
将Array数组进行逆置
int left=0;
int right=Arraypos-1;
while(left<right)//将数组逆置
{
int tmp=Array[left];
Array[left]=Array[right];
Array[right]=tmp;
left++;
right--;
}
四、完整代码
int* addToArrayForm(int* num, int numSize, int k, int* returnSize) {
int Ksize=0;
int tmp=k;
while(tmp)
{
tmp/=10;
Ksize++;//计算数字k的位数
}
int lenth=(numSize>Ksize)?(numSize):(Ksize);
int* Array=(int*)malloc(sizeof(int)*(lenth+1));//开辟一个新的数组
int Arraypos=0;//num数组开始位置
int numpos=numSize-1;//num数组末尾位置
int carry=0;//进位标志
while(lenth--)
{
int a;
if(numpos<0)
a=0;//数组长度比k位数小
else
a=num[numpos];
Array[Arraypos]=k%10+a+carry;//将每一位的数逆序存入新数组
k/=10;
if(Array[Arraypos]>9)
{
Array[Arraypos]-=10;
carry=1;
}
else
carry=0;
Arraypos++;
numpos--;
}
if(carry==1)//循环结束carry仍为1,还有一个进位未处理
{
Array[Arraypos]=1;
Arraypos++;
}
int left=0;
int right=Arraypos-1;
while(left<right)//将数组逆置
{
int tmp=Array[left];
Array[left]=Array[right];
Array[right]=tmp;
left++;
right--;
}
*returnSize=Arraypos;
return Array;//返回新数组
}