美文网首页
12.大数相乘

12.大数相乘

作者: percykuang | 来源:发表于2019-10-19 13:51 被阅读0次

题目

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

示例 1:

输入: num1 = "2", num2 = "3"
输出: "6"
示例 2:

输入: num1 = "123", num2 = "456"
输出: "56088"
说明:

num1 和 num2 的长度小于110。
num1 和 num2 只包含数字 0-9。
num1 和 num2 均不以零开头,除非是数字 0 本身。
不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。

code1(竖式乘法)

// 经典竖式乘法:
// 999
// 234
//------------------
// 999 * 4  -->      3996
// 999 * 3  -->     29970
// 999 * 2  -->  + 199800
//--------------------------------
//                 result

/**
 * 实现一个字符串和一个字符的乘法
 * @param {*} s1 
 * @param {*} ch 
 */
function simpleMultiply(s1, ch) {
  // 保存字符与字符的乘积
  let product = 0
  // 保存进位
  let carry = 0
  // 保存结果的数组
  const res = []
  for (let i = s1.length - 1; i >= 0; i--) {
    product = +s1[i] * +ch + carry
    if (product > 9) {
      carry = parseInt(product / 10)
    } else {
      carry = 0
    }
    res.unshift(product % 10)
  }
  if (carry)  res.unshift(carry)

  return res.join('')
}

/**
 * 实现两个字符串的加法
 * @param {*} s1 
 * @param {*} s2 
 */
function twoNumberSum(s1, s2) {
  // 这个下标用来辅助补0
  let cur = 0
  while (cur < s1.length || cur < s2.length) {
    if (!s1[cur]) {
      s1 = '0' + s1
    }
    if (!s2[cur]) {
      s2 = '0' + s2 
    }
    cur++
  }
  // 保存进位
  let carry = 0
  // 保存结果的数组
  const res = []
  // 一次计算的和
  let sum = 0
  for (let i = s1.length - 1; i >= 0; i--) {
    sum = +s1[i] + +s2[i] + carry
    if (sum > 9) {
      carry = 1
    } else {
      carry = 0
    }
    res.unshift(sum % 10)
  }
  if (carry)  res.unshift(carry)
  return res.join('')
}

/**
 * 实现两个字符串的乘法
 * @param {*} s1 
 * @param {*} s2 
 */
function multiply(s1, s2) {

  if (s1 === '0' || s2 === '0') return '0'

  s2 = s2.split('')

  let ch = ''
  // 乘积
  let product = ''
  // 进位
  let carry = ''
  // 上一次乘积 + 当前这次乘积的结果
  let total = ''
  while ((ch = s2.pop()) !== undefined) {
    product = simpleMultiply(s1, ch) + carry
    total = twoNumberSum(total, product)
    carry = '0' + carry
  }
  return total
}

code2 (优化版竖式乘法)

test.png
function multiply(s1, s2) {
  if (s1 === '0' || s2 === '0') return '0'
  // 结果数组最多有 s1.length + s2.length 位
  const res = new Array(s1.length + s2.length).fill(0)
  let sum = 0

  for (let i = s1.length - 1; i >= 0; i--) {
    let a = +s1[i]
    for (let j = s2.length - 1; j >= 0; j--) {
      let b = +s2[j]
       // 核心算法
      sum = res[i + j + 1] + a * b
      res[i + j + 1] = sum % 10
      // `| 0` 在这里的意思是对前面的数值进行取整
      res[i + j] = res[i + j] + sum / 10 | 0
    }
  } 

  if (res[0] === 0) res.shift() 
  
  return res.join('')
  
}

相关文章

  • 12.大数相乘

    题目 code1(竖式乘法) code2 (优化版竖式乘法)

  • 大数相乘--golang简单实现

    大数乘法之golang实现所谓大数相乘(Multiplication algorithm),就是指数字比较大,相乘...

  • 大数相乘

    所谓大数相乘(Multiplication algorithm),就是指数字比较大,相乘的结果超出了基本类型的表示...

  • 大数相乘

  • 大数相乘

    两个大数相乘,这两个大数分别是a和b,现在分割成两部分,每一部分都是N位,假设是10进制的,其实对于2进制也同样适...

  • 大数相乘

  • 大数相乘

    别忘了把字符串反转便于求导,还有去除前面的0的时候别忘了结果本来就为0的情况,两个数相乘最长长度为len1+len2。

  • 大数相乘

    给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示...

  • 小算法集锦 : 20行代码实现大数相乘

    1.大数相乘 1.1 js 版本 (不计算注释只需要20行) 1.2 C语言 大数相乘 无依赖 简单的 js 转...

  • 大数相乘算法

    1、计算两个大数相乘的结果。2、算法流程:(1)大数可能超出任何一种整数类型,会引发溢出问题,所以用字符串的格式存...

网友评论

      本文标题:12.大数相乘

      本文链接:https://www.haomeiwen.com/subject/loggmctx.html