纪念我的第一次4kyu 【大道化简之无长度限制的加法】

288 阅读2分钟

ISSUE

We need to sum big numbers and we require your help.

Write a function that returns the sum of two numbers. The input numbers are strings and the function must return a string.

Example

add("123", "321"); -> "444"
add("11", "99");   -> "110"

Notes

  • The input numbers are big.
  • The input is a string of only digits
  • The numbers are positives

翻译

我们需要求和,我们需要你的帮助。 编写一个返回两个数字之和的函数。输入的数字是字符串,函数必须返回字符串。

注:

  • 输入的数字很大。
  • 输入是一个只有数字的字符串
  • 这些数字是正数

前奏

Number?+ toString?

  • 当然不是,第一时间想到的方法已经写出来了,要的就是修复这个问题, 什么问题呢,就是数值太大回导致精度忽略的问题。
  • 那么我想到的是我们做加法的时候是不会出现这种问题
  • 可以当作是考虑手撕进制的问题
  • 真是大道至简啊 真有意思
/**
 * @author zowie
 * @param {number} a,b
 * @return {boolean}
 */

function add(a, b) {
  result = []
  var flag = 0
  var aa = (a + '').split('').reverse()
  var ba = (b + '').split('').reverse()
  for (let i = 0; i < (aa.length <= ba.length ? aa.length : ba.length); i++) {
    if ((Number(aa[i]) + Number(ba[i]) + flag + '')[1]) { //需要近位的情况
      result.push((Number(aa[i]) + Number(ba[i]) + flag + '')[1])
      flag = Number((Number(aa[i]) + Number(ba[i]) + flag + '')[0])
    } else {
      result.push((Number(aa[i]) + Number(ba[i]) + flag + '')[0])
      flag = 0
    }
  }
  if (aa.length <= ba.length) {
    let temp = aa
    aa = ba
    ba = temp
  }
  let num = ba.length
  for (let i = num; i < aa.length; i++) {//处理更长整数与上面计算结果核并
    if ((Number(aa[i]) + flag + '')[1]) {
      result.push((Number(aa[i]) + flag + '')[1])
      flag = Number((Number(aa[i]) + flag + '')[0])
    } else {
      result.push((Number(aa[i]) + flag + '')[0])
      flag = 0
    }
  }
  if (flag != 0) { result.push(flag.toString()) } //若最后一次计算有进位的情况
  return result.reverse().join('')
}
console.log(add('63829983432984289347293874', '90938498237058927340892374089'))
//  "91002328220491911630239667963"

// --------------------------------------------------------------------------------------------------------------
function add(a, b) {
  console.log(a, b);
  a = a.split("").reverse();
  b = b.split("").reverse();

  var sum = [];
  var remainder = 0;
  for (var i = 0; i < Math.max(a.length, b.length); i++) {
    var x = parseInt(a[i]) ? parseInt(a[i]) : 0;
    var y = parseInt(b[i]) ? parseInt(b[i]) : 0;
    var digit = (x + y + remainder) % 10;
    remainder = Math.floor((x + y + remainder) / 10);
    sum.unshift(digit);
  }
  if (remainder) { sum.unshift(remainder) }

  return sum.join("");
}
// --------------------------------------------------------------------------------------------------------------
function add(a, b) {
  const arrA = a.split(''), arrB = b.split('');
  const arrToNormalize = arrA.length > arrB.length ? arrB : arrA;
  while (arrA.length != arrB.length) {
    arrToNormalize.unshift(0);
  }
  return arrA
    .reduceRight((sumArr, value, index, arr) => {
      let sum = Number(value) + Number(arrB[index]);
      if (sumArr.length == arrB.length - index) {
        sum += sumArr.shift();
      }
      if (sum > 9) {
        sumArr.unshift(sum - 10);
        sumArr.unshift(1);
      } else {
        sumArr.unshift(sum);
      }

      return sumArr;
    }, [])
    .join('');
}
// --------------------------------------------------------------------------------------------------------------
const add = (a, b) =>
  ((a, b, c) => [...a].reduceRight((pre, val, idx) => (sum => (c = sum / 10 ^ 0, sum % 10 + pre))(+val + +b[idx] + c), ``).replace(/^0+/, ``))
    (a.padStart(Math.max(a.length, b.length) + 1, `0`), b.padStart(Math.max(a.length, b.length) + 1, `0`), 0);
// --------------------------------------------------------------------------------------------------------------
const add = (a, b) => ((s = ((a = a.split("")).length > (b = b.split("")).length ? a : b)
  .reduceRight(s => ({ s: (s.c += ~~a.pop() + ~~b.pop()) % 10 + s.s, c: ~~(s.c / 10) }), { s: "", c: 0 })).c == 0 ? "" : s.c) + s.s;
// --------------------------------------------------------------------------------------------------------------
function add(a, b) {
  let result = [];
  let maxLength = a.length > b.length ? a.length : b.length;
  a = a.padStart(maxLength, 0);
  b = b.padStart(maxLength, 0);

  let carry = 0;
  for (let i = maxLength - 1; i >= 0; i--) {
    let sumOfDigits = +a[i] + +b[i] + carry;
    carry = sumOfDigits >= 10 ? 1 : 0;
    sumOfDigits = String(sumOfDigits);

    result.unshift(sumOfDigits[sumOfDigits.length - 1]);
  }

  if (carry == 1) result.unshift(carry);

  return result.join("");
}
// --------------------------------------------------------------------------------------------------------------

const add = (a, b, r = 0) => (res => a == b && b == "" && r == 0 ? "" : add(a.slice(0, -1), b.slice(0, -1), r = ~~(res / 10)) + res % 10)(+a.slice(-1) + +b.slice(-1) + +r).replace(/^0+/g, "");
// --------------------------------------------------------------------------------------------------------------

add = (a, b, c = a => ('0'.repeat(150) + a).slice(-150), d = c(a), e = c(b)) => [...e].reduceRight(([a, b], c, e) => [((f = +c + +d[e] + b) % 10) + a, f / 10 | 0], ['', 0])[0].replace(/^0+/, '')