每日一题:415. 字符串相加

64 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第13天,点击查看活动详情

一、题目描述:

415. 字符串相加

给定两个字符串形式的非负整数 num1num2 ,计算它们的和并同样以字符串形式返回。

你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。

示例 1:

输入:num1 = "11", num2 = "123"
输出:"134"

示例 2:

输入:num1 = "456", num2 = "77"
输出:"533"

示例 3:

输入:num1 = "0", num2 = "0"
输出:"0"

提示:

  • 1 <= num1.length, num2.length <= 10^4
  • num1 和num2 都只包含数字 0-9
  • num1 和num2 都不包含任何前导零

二、思路分析:

申请个存结果的空间,空间大小要比参数中的两个字符串中最长的strlen还要长2位,一位用于结尾存结束符\0,另一个用于最高位预留的进位。

下标unit1-i unit2-i unit-i分别表示两个入参和结果的位下标,起始i=0即代表各自的个位数;

carrybit用于标记当前位累加超过10时需要进位1,当前位累加也应考虑这位,用完记得清零; 预留的ret[0]要不要用,只需要考虑上一次计算是否有进位。

返回字串之前记得检查预留的一位是否使用,没使用需要将字符串指针跳过这个空的字符。

三、AC 代码:

char * addStrings(char * num1, char * num2){
    int len1=strlen(num1);
    int len2=strlen(num2);
    int unit1=len1-1;//个位数下标
    int unit2=len2-1;
    int cnt=(len1>=len2)?len2:len1;//位数少的那个数决定需要进行多少次累加
    int leftcnt=(len1>=len2)?len1-len2:len2-len1;
    int len=(len1>=len2)?len1+2:len2+2;//存结果的长度,多出两位:一个存可能出现的最高位进位,一个存结束符'\0'
    char *ret=(char*)malloc((len)*sizeof(char));
    int unit=len-2;//len-1下标给了'\0'
    ret[0]=0;
    ret[len-1]='\0';
    int carrybit=0;
    int i=0;
    for(;i<cnt;i++)
    {
        ret[unit-i]=(num1[unit1-i]-'0'+num2[unit2-i]-'0'+carrybit)%10+'0';
        if((num1[unit1-i]-'0'+num2[unit2-i]-'0'+carrybit)>=10)
        {
            carrybit=1;
            continue;
        }
        carrybit=0;//使用完进位,清零
    }
    //接下来处理两个相加数中,较多位数的多出来的高位
    //printf("unit-i: %d\n",unit-i);
    //printf("i:%d\n",i);
    //printf("cnt: %d\n",cnt);
    //printf("leftcnt: %d\n",leftcnt);
    for(;i<cnt+leftcnt+1;i++)//多一位,为新增的保留的最高位进位
    {
        if(i!=cnt+leftcnt)//还有剩余的高位未填
        {
            ret[unit-i]=(len1>=len2)?(num1[unit1-i]-'0'+carrybit)%10+'0':(num2[unit2-i]-'0'+carrybit)%10+'0';
            int temp=(len1>=len2)?(num1[unit1-i]-'0'+carrybit):(num2[unit2-i]-'0'+carrybit);
            if(temp>=10)
            {
                carrybit=1;
                continue;
            }
            carrybit=0;//使用完进位,清零
        }
        else if(carrybit==1)
            ret[unit-i]=carrybit+'0';
    }

    while(*ret==0)//忽略掉开头的空字符
        ret++;
return ret;
}