两个字符串大数的加法

描述

以字符串的形式读入两个数字,编写一个函数计算它们的和,以字符串形式返回。

数据范围: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;
    }
};

猜你喜欢

转载自blog.csdn.net/jingerppp/article/details/131305135