【前端也得会算法】415. 字符串相加 [ 简单 ]

166 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

一、题目描述:

给定两个字符串形式的非负整数 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 都不包含任何前导零

二、题解:

方法一 按位补零叠加法

  • 原理。使用charCodeAt得到ASCII码,ASCII码其实就是数值型,记录数字相加进位就行。
  • 思路。
    • 使用'0'.charCodeAt(0)得到校准数字
    • 使用字符串数字转化为ASCII码再减去校准数字得到真实值,再计算两个数的和
    • 结果累计余数
    • diff判断取余

代码:

var addStrings = function(num1, num2) {
    let maxLen = num1.length - num2.length>0?num1.length:num2.length
    num1 = num1.padStart(maxLen,'0')
    num2 = num2.padStart(maxLen,'0')
    let flagNum = '0'.charCodeAt(0)
    let add = 0
    let result = ''
    while(maxLen>0){
        maxLen--
        let sum = num1[maxLen].charCodeAt(0)  + num2[maxLen].charCodeAt(0)- flagNum * 2
        let diff = sum + add
        result += (diff<10?diff:diff-10) +''
        if(diff>=10){
            add = 1
        } else {
            add = 0
        }
        
    }
    result+= add?add:''
    return result.split('').reverse().join('')
};

image.png

代码略显冗长,且不优雅,优化一下:

var addStrings = function(num1, num2) {
    let maxLen = num1.length - num2.length>0?num1.length:num2.length
    num1 = num1.padStart(maxLen,'0')
    num2 = num2.padStart(maxLen,'0')
    let flagNum = '0'.charCodeAt(0)
    let add = 0
    let result = ''
    while(maxLen>0){
        maxLen--
        let sum = num1[maxLen].charCodeAt(0)  + num2[maxLen].charCodeAt(0)- flagNum * 2
        let diff = sum + add
        result += diff % 10
        add = diff / 10 | 0
    }
    result+= add || ''
    return result.split('').reverse().join('')
};

image.png

偷个鸡,隐式转化为数值型:

var addStrings = function(num1, num2) {
    let maxLen = num1.length - num2.length>0?num1.length:num2.length
    num1 = num1.padStart(maxLen,'0')
    num2 = num2.padStart(maxLen,'0')
    let add = 0
    let result = ''
    while(maxLen>0){
        maxLen--
        let sum = num1[maxLen] - (num2[maxLen])*-1
        // let sum = +num1[maxLen] + +num2[maxLen]
        let diff = sum + add
        result += diff % 10
        add = diff / 10 | 0
    }
    result+= add || ''
    return result.split('').reverse().join('')
};

image.png

方法二 双索引法

  • 原理。与方案一相同,但是不进行部位,如果索引为负则取0即可。

代码:

var addStrings = function(num1, num2) {
    let i=num1.length-1, j=num2.length-1
    let add = 0
    let result = ''
    while(i >=0 || j >= 0){
        let sum = (i>=0?+num1[i]:0) + (j>=0?+num2[j]:0)
        let diff = sum + add
        result += diff % 10
        add = diff / 10 | 0
        i--
        j--
    }
    result+= add || ''
    return result.split('').reverse().join('')
};

image.png

优化一下代码:

var addStrings = function(num1, num2) {
    let i=num1.length-1, j=num2.length-1
    let add = 0
    let result = ''
    let sum = 0
    let diff = 0
    while(i >=0 || j >= 0 || add>0){
        sum = (i>=0?+num1[i]:0) + (j>=0?+num2[j]:0)
        diff = sum + add
        result += diff % 10
        add = diff / 10 | 0
        i--
        j--
    }
    return result.split('').reverse().join('')
};

image.png

将字符串拼接换成数组,则代码:

var addStrings = function(num1, num2) {
    let i=num1.length-1, j=num2.length-1
    let add = 0
    let result = []
    let sum = 0
    let diff = 0
    while(i >=0 || j >= 0 || add>0){
        sum = (i>=0?+num1[i]:0) + (j>=0?+num2[j]:0)
        diff = sum + add
        result.push(diff % 10)
        add = diff / 10 | 0
        i--
        j--
    }
    return result.reverse().join('')
};

image.png 三、总结

  • 此题可以按位补零叠加法双索引法两种方案
  • 按位补零叠加法主要是使用charCodeAt得到ASCII码,ASCII码其实就是数值型,记录数字相加进位就行。
  • 双索引法与方案一相同,但是不进行部位,如果索引为负则取0即可。

文中如有错误,欢迎在评论区指正