本文正在参与掘金团队号上线活动,点击 查看大厂春招职位
一、题目描述
给出两个很大的整数,求出两个整数之和。
示例:
输入:['813257907624', '92135218459']
输出:'905393126083'
二、思路分析
首先我们来回想一下列竖式(也就是加、减、乘、除的计算过程):
813257907624
+ 92135218459
----------------
905393126083
那么,我们为什么要使用列竖式来进行运算呢?
因为对于这么大的整数进行相加,是无法直接计算出结果的,所以需要把计算的过程拆解为一个又一个的子过程。
打个比方 624 + 459 是不是相对来说计算起来比较麻烦,那么 4 + 9、2 + 5 + 1、6 + 4 计算起来是不是就没有那么麻烦了?
实际上使用程序来计算也是一样的。
我们只需要把一个大运算,拆解成若干个小运算,就像列竖式一样的进行按位计算,即可。
注: 需要注意的是,因为整数非常的大,超过了 Number 类型的长度,所以一般是使用字符串或者数组进行表示的,那么展示的时候一般是以字符串的形式,计算的时候一般是以数组的形式。
三、AC 代码
/**
* 合并剩余不用进行计算的数值
* @param { String[] } arr 剩余数值的数组
* @param { Number } rec 进位
* @param { Number[] } res 计算后的数组
*/
function mergeSurplusString(arr, rec, res) {
if(arr.length && rec) {
arr[arr.length - 1] = Number(arr[arr.length - 1]) + rec
res.unshift(...arr)
}
}
/**
* 合并剩余不用进行计算的数值
* @param { String } s1 整数 1
* @param { String } s2 整数 2
* @returns { String } 计算后的数值
*/
function sum (s1, s2) {
// 传参类型判断
if( typeof s1 !== 'string' || typeof s2 !== 'string' ) {
throw new TypeError('参数不是字符串')
}
// 分割字符串为数组
const _s1 = s1.split('')
const _s2 = s2.split('')
// 进位
let rec = 0
// 计算结果
const res = []
// 当 s1 和 s2 都有数值的情况,需要进行按位运算
while(_s1.length && _s2.length) {
// 获取 末尾 的数值 (因为计算是从个位开始算的,当然也可以反转数组后从数组头部开始计算)
const p1 = _s1.pop()
const p2 = _s2.pop()
// 计算和
const sum = Number(p1) + Number(p2) + rec
// 获取进位
rec = Math.floor(sum / 10)
// 获取个位
res.unshift(sum % 10)
}
// 合并剩余的数值
mergeSurplusString(_s1, rec, res)
mergeSurplusString(_s2, rec, res)
// 返回计算后的字符串
return res.join('')
}
console.log('sum:', sum('813257907624', '92135218459')) // sum: 905393126083
四、总结
大数相加是一道非常经典的题目哈,面试中出现的概率相当之大,而且是一道在业务场景中用的到的算法,所以还是很重要的。
其实关键点就是 列竖式 ,然后按位去逐个的进行运算。
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情