描述
以字符串的形式读入两个数字,编写一个函数计算它们的和,以字符串形式返回。
数据范围:s.length,t.length≤100000,字符串仅由'0'~‘9’构成
要求:时间复杂度O(n)
示例1:
输入:"1","99"
返回值:"100"
说明:1+99=100
示例2:
输入:"114514",""
返回值:"114514"
C语言解题思路:
两个数的位数超级大,所以,无法将字符串转换成整数相加,即只能通过字符串进行竖式计算。
竖式计算,需要考虑的就是进位问题,
- 两个字符相加超过10(ASCII 码相加需要超过106),则需要进行取舍进位;
- 两个字符相加不超过10(ASCII 码相加不超过106),则转换为有效字符(减掉字符 0);
另外,需要考虑的问题是目标字符串。如果最高位在计算之后不存在进位,当然是可以直接利用源字符串,这样空间上可以省下来。但实际上如果最高位为9,考虑到进位1 之后,需要再向前多加一位。所以,这样就要求返回的目标字符串只能新建,并且位数要比源字符串最长的还要多1位,即 strlen() + 2(考虑结尾\0)。
流程大致如下:
- 确定目标字符串的长度,max + 2;
- 随机将一个字符串memcpy() 给目标字符串;
- 使用目标字符串同另一个字符串进行加法运算,考虑到进位,进位直接在目标字符串的前一个字符上加1;
- 当第二个字符串加法运算结束,需要考虑目标字符串的进位问题,即上一步的前一个字符是否需要继续进位;
- 返回目标字符串时,同样需要考虑是否存在了进位,如果没有进位,返回result + 1;
代码:
**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 计算两个数之和
* @param s string字符串 表示第一个整数
* @param t string字符串 表示第二个整数
* @return string字符串
*/
char* solve(char* s, char* t ) {
if (s == NULL) {
return t;
}
if (t == NULL) {
return s;
}
int sLen= strlen(s);
int tLen = strlen(t);
if (!sLen) {
return t;
}
if (!tLen) {
return s;
}
char* result = 0;
int rLen = 0;
if (sLen > tLen) {
rLen = sLen + 2;
} else {
rLen = tLen + 2;
}
result = (char*)malloc(rLen);
memset(result, '0', rLen);
rLen -= 1;
memcpy(result + rLen - sLen, s, sLen + 1);
int temp = 0;
int i = 0;
int j = 0;
for (i = tLen - 1, j = rLen - 1; i >= 0; --i, --j) {
temp = *(result + j) + *(t + i);
if (temp >= 106) {
*(result + j) = temp - 106 + '0';
*(result + j - 1) += 1;
} else {
*(result + j) = temp - '0';
}
}
for (j = j; j >=0; --j) {
if (*(result + j) < 106) {
break;
}
*(result + j) = *(result + j) - 106 + '0';
*(result + j - 1 ) = '1';
}
return *result == '0' ? result + 1: result;
}
C++ 解题思路:
对于C++ 解题可能偏简单些,利用string 类的函数 empty() 确认有效性。接着对两个字符串进行对齐操作处理,在短的字符串前加上 '0' 字符。接下来考虑加法运算,如果有进位则存放在carry 变量中。最后加法运算结束后,需要重新考虑carrry 这个进位。
代码:
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 计算两个数之和
* @param s string字符串 表示第一个整数
* @param t string字符串 表示第二个整数
* @return string字符串
*/
string solve(string s, string t) {
if (s.empty())return t;
if (t.empty())return s;
if (s.size() < t.size())swap(t, s);
int tail = s.size() - t.size();
int carry = 0, tmp = 0;
while (tail--) t = '0' + t;
for (int i = s.size() - 1; i >= 0; i--) {
tmp = s[i] - '0' + t[i] - '0' + carry;
if (tmp >= 10) {
carry = 1;
tmp -= 10;
} else {
carry = 0;
}
s[i] = tmp + '0';
}
if (carry == 1) {
s = '1' + s;
}
return s;
}
};