地址:
力扣https://leetcode-cn.com/problems/add-strings/
题目:
给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和并同样以字符串形式返回。
你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。
示例 1:
输入:num1 = "11", num2 = "123" 输出:"134" |
示例 2:
输入:num1 = "456", num2 = "77" 输出:"533" |
示例 3:
输入:num1 = "0", num2 = "0" 输出:"0" |
提示:
1 <= num1.length, num2.length <= 104 num1 和num2 都只包含数字 0-9 num1 和num2 都不包含任何前导零 |
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-strings
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
题目限定不能把字符串转换为整数,但没有说不能把其中每个字符转为数字
字符与对应数字是存在关系的,ASCII 关系
字符 | 十进制数 |
0 | 48 |
1 | 49 |
2 | 50 |
3 | 51 |
4 | 52 |
5 | 53 |
6 | 54 |
7 | 55 |
8 | 56 |
9 | 57 |
比如字符 '5',可以通过 '5' - '0' 等于十进制 53 - 48 = 5
同理数字转字符则 + '0' 即可
处理完字符与数字的问题,剩下的就是竖式计算加法,需要考虑进位问题
比如: 987 + 25 = 1012
个位 7 + 5 + 进位 0 = 12, 结果个位 12 % 10 = 2, 进位 12 / 10 = 1
十位 8 + 2 + 进位 1 = 11, 结果十位 11 % 10 =1,进位 11 / 10 = 1
百位 9 + 0 + 进位 1 = 10,结果百位 10 % 10 = 0,进位 10 / 10 = 1
千位 0 + 0 + 进位 1 = 1,结果千位 1 % 10 = 1, 进位 1 /10 = 0
(竖式相加如果对应位没有字符,表示该数完成,对应位加法相当于加 0)
这样就得到了 1012
在 C 语言中没有其他语言那样可以直接类似 str.appand 依次将个位,十位直接拷贝到数组末
所以我们要多做一次反向字符串操作
另外两个数长度不一定相同,考虑进位情况,新的字符串长度为 输入的两个数组其中较长哪个的长度 + 1(进位)
方法一、逐个字符加法
#define max(a, b) ((a) >= (b) ? (a) : (b))
void swap(char *x, char *y)
{
*x = (*x)^(*y);
*y = (*x)^(*y);
*x = (*x)^(*y);
}
void swapString(char *s)
{
int sLen = strlen(s);
int mid = sLen/2;
int i;
for(i=0; i<mid; i++)
swap(&s[i], &s[sLen-i-1]);
}
char * addStrings(char * num1, char * num2){
int sLen1 = strlen(num1);
int sLen2 = strlen(num2);
int sLen = max(sLen1, sLen2) + 1;
char *ret = (char *)malloc(sizeof(char) * sLen + 1);
int i,j,k;
int carry = 0;
for(i=sLen1-1, j=sLen2-1, k=0; i>=0 || j>=0; i--, j--)
{
int a = i<0 ? 0 : num1[i] - '0';
int b = j<0 ? 0 : num2[j] - '0';
//printf("a=%d, b=%d, carry=%d\n", a, b, carry);
char c = (a+b+carry)%10 + '0';
ret[k++] = c;
carry = (a+b+carry)/10;
}
if(carry != 0)
ret[k++] = carry +'0';
ret[k]='\0';
swapString(ret);
return ret;
}