Multiply Strings - 使用JavaScript的[Leetcode]

时间:2017-02-12 18:22:08

标签: javascript algorithm

我一直在解决这个问题太久了,我似乎无法找到我的逻辑错误。

提示:

  

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

     

注意:

     

num1和num2的长度都是< 110.

     

num1和num2都包含   只有数字0-9。

     

num1和num2都不包含任何前导零。

     

您不得使用任何内置BigInteger库或转换输入   直接整数。

这是我的尝试:



c




本质上逻辑是我可以添加var multiply = function(num1, num2) { var result = 0; // if any of the nums is 0, automatically it is zero if (num1[0] === '0' || num2[0] === '0') { return '0' }; var length1 = num1.length - 1; var length2 = num2.length - 1; var counterI = 0; var iBase10 = 1; for (var i = length1; i >= 0; i--) { iBase10 = Math.pow(10, counterI) counterI++; var counterJ = 0 var jBase10 = 1; for (var j = length2; j >= 0; j--) { jBase10 = Math.pow(10, counterJ) counterJ++; result += (num1[i] * iBase10) * (num2[j] * jBase10) } } return result.toString() }; var result = multiply("123456789", "987654321"); console.log(result); // should be 121932631112635269每个乘法我从字符串的右边开始到左边(​​到所有可能的组合,因此嵌套的for循环)。

当索引向左移动时,result增加到10的幂,因此每个计算都会相应地设置。

但是,当我输入时,我似乎无法找到错误的内容:

base10

我得到的结果是var result = multiply("123456789","987654321"); ,但实际答案是121932631112635260

我稍微接近答案!

2 个答案:

答案 0 :(得分:2)

您的实际结果不准确,因为您将结果存储在一个单一的数字类型变量中,并且中间变量 iBase10 jBase10 在某一点上会变得不准确。 JavaScript使用64位浮点数来存储数字,因此对于具有大约17或更多十进制数字的数字,此表示会失去准确性。这就是为什么你得到最后的0位而不是9位。

相反,您需要处理较小的数字,并保持在JavaScript可以管理的范围内。最终结果应该是一个字符串,因为只要将其转换为数字,就会出现不准确的情况。

这是一个简单的实现,它模仿你在一张纸上做的事情:你计算每个数字1的数字的产品,每个数字的数字2,并将这些产品加在数字位置的正确数字位置结果,将任何溢出转移到下一个数字:

    123 
    456
------- *
    738      <--- intermediate products
   615
  492
------- +
  56088     <---- sum of those products

var multiply = function(num1, num2) {
    // Result can have at most this number of digits:
    var result = Array(num1.length + num2.length).fill(0);
    for (var j = num2.length - 1; j >= 0; j--) {
        // k is the index in the result: where to add to 
        var k = num1.length + j;
        var overflow = 0;
        for (var i = num1.length - 1; i >= 0; i--) {
            product = num2[j] * num1[i] + overflow + result[k];
            result[k] = product % 10;
            overflow = (product - result[k]) / 10;
            k--;
        }
        result[k] += overflow;
    }
    // Convert result to string, removing any prepadded zeroes
    return result.join('').replace(/^0+(.)/, '$1');
}

// I/O handling
var inputs = document.querySelectorAll('input');
var output = document.querySelector('span');

inputs[0].oninput = calculate;
inputs[1].oninput = calculate;

function calculate() {
  output.textContent = multiply(inputs[0].value, inputs[1].value);
}
input { width: 40em }
Number 1: <input><br>
Number 2: <input><br>
Product: <span></span>

有更智能的算法,例如Karatsuba algorithm,它们使用较少的操作来获得正确的产品。

答案 1 :(得分:0)

var multiply = function(num1, num2) {
let product = new Array(num1.length + num2.length).fill(0)
for (let i = num1.length; i--;) {
    let carry = 0
    for (let j = num2.length; j--;) {
        product[1 + i + j] += carry + num1[i] * num2[j]
        carry = Math.floor(product[1+i+j] / 10);
        product[1 + i + j] = product[1 + i + j] % 10
    }
    product[i] += carry
}
return product.join("").replace(/^0*(\d)/, "$1");
};

OR

var multiply = function(a, b) {
   return (BigInt(a)*BigInt(b)).toString()
};