本机环境:64位Centos 7.4,vim、gcc编译工具。
假设用户输入的数据保存在数组adda,addb中,如果手工计算,就是从低位到高位依次先加,满十进一,那么有两个问题需要解决。
- 问题:
1、用数组保存结果,那么结果的长度是多少位?
两个数相加,结果最大也只能比较大的那个数多一位。
lensum = lena > lenb ? lena : lenb;
lensum++; //确定结果数组的长度lensum
2、怎么设计满十进一的算法?
如果没加一位,就对这一位判断是否需要进位,这样问题就会变复杂,可以先保存每一位相加的结果,然后对最终的结果数组进行处理。
两个数,adda = 1234567, addb = 678;
数组adda | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
数组addb | 6 | 7 | 8 | ||||
数组result | 1 | 2 | 3 | 4 | 11 | 13 | 15 |
然后一次性对 result 数组进行处理。
for(i = lensun - 1; i > 0; i --)
{
if(result[i] > 9)
{
result[i] = result[i] % 10;
result[i-1] += 1;
}
}
实际上需要注意的是,数组首位下标为0,就是说 7+8 的结果会存在 result [ 0 ] 中,上面的表格是为了便于理解。
编码实现
char* bigadd(char *adda, int lena, char *addb, int lenb)
{ //加法运算的方法。
int num = '0', i, k, j, tmp;
for (i = 0; i<lena; i++)
{ //将字符编码的数字转换为对应的数,
adda[i] = adda[i] - num; //例如6实际在字符串中存储的是54,
} //减去0对应的48得到真实的6存储在字符数组中。
for (i = 0; i<lenb; i++)
{
addb[i] = addb[i] - num;
}
int lensum; //求出结果数组的长度。
lensum = lena>lenb ? lena : lenb;
lensum++;
char *result, final[BUFSIZ]; //result用于返回结果集,final数组用于整理结果集。
result = (char*)calloc(lensum, 1);
for (i = 0, j = 0; i<lena&&j<lenb; i++, j++) //循环的给每一位作加法
{
result[i] = adda[lena - i - 1] + addb[lenb - i - 1];
}
if (lena>lenb)
{ //使用判断将较大数的高位也写入结果数组
for (i = lenb; i<lena; i++)
{
result[i] = adda[lena - i - 1];
}
}
if (lenb>lena){
for (i = lena; i<lenb; i++)
{
result[i] = addb[lenb - i - 1];
}
}
for (k = 0; k<lensum - 1; k++)
{ //整理结果数组的每一位,满10进一。
if (result[k]>9){
tmp = result[k] / 10;
result[k] = result[k] % 10;
result[k + 1] += tmp;
}
}
j = 0;
if (result[lensum - 1] != 0)
{ //去掉前前导0将结果处理后写到final数组中。
final[j] = result[lensum - 1] + '0';
j++;
}
for (i = lensum - 2; i >= 0; i--)
{
final[j++] = result[i] + '0';
}
result = final; //再把result指针指向final数组中,并返回result指针。
return result;
}