字符串乘法

对于比较小的数字,作运算能够直接使用编程语言提供的运算符,可是若是相乘的两个因数很是大,语言提供的数据类型可能就会溢出。一种替代方案就是,运算数以字符串的形式输入,而后模仿咱们小学学习的乘法算术过程计算出结果,而且也用字符串表示。git

cf156dd74e7d5068474e1e440812744e.jpg

须要注意的是,num1 和 num2 能够很是长,因此不能够把他们直接转成整型而后运算,惟一的思路就是模仿咱们手算乘法。算法

好比说咱们手算 123 × 45,应该会这样计算:编程

81babfa8b7aa21834217b4ff99aa3f34.jpeg

计算 123 × 5,再计算 123 × 4,最后错一位相加。这个流程恐怕小学生均可以熟练完成,可是你是否能把这个运算过程进一步机械化,写成一套算法指令让没有任何智商的计算机来执行呢?数组

PS:我认真写了 100 多篇原创,手把手刷 200 道力扣题目,所有发布在 labuladong的算法小抄,持续更新。建议收藏,按照个人文章顺序刷题,掌握各类算法套路后投再入题海就如鱼得水了。编程语言

你看这个简单过程,其中涉及乘法进位,涉及错位相加,还涉及加法进位;并且还有一些不易察觉的问题,好比说两位数乘以两位数,结果多是四位数,也多是三位数,你怎么想出一个标准化的处理方式?这就是算法的魅力,若是没有计算机思惟,简单的问题可能都没办法自动化处理。ide

首先,咱们这种手算方式仍是太「高级」了,咱们要再「低级」一点,123 × 5 和 123 × 4 的过程还能够进一步分解,最后再相加:学习

f51580ef18f3566e498ba92ae75ea0b7.jpeg

如今 123 并不大,若是是个很大的数字的话,是没法直接计算乘积的。咱们能够用一个数组在底下接收相加结果:spa

51892098e32571f0cfdec9c7c9545b78.jpeg

整个计算过程大概是这样,有两个指针 i,j 在 num1 和 num2 上游走,计算乘积,同时将乘积叠加到 res 的正确位置翻译

b5f5395a512e57edb58ac920a5bcd531.gif

如今还有一个关键问题,如何将乘积叠加到 res 的正确位置,或者说,如何经过 i,j 计算 res 的对应索引呢?3d

其实,细心观察以后就发现,num1[i] 和 num2[j] 的乘积对应的就是 res[i+j] 和 res[i+j+1] 这两个位置

445160f2613a13d1a2871e0652970d8c.jpeg

明白了这一点,就能够用代码模仿出这个计算过程了:

string multiply(string num1, string num2) {
    int m = num1.size(), n = num2.size();
    // 结果最多为 m + n 位数
    vector<int> res(m + n, 0);
    // 从个位数开始逐位相乘
    for (int i = m - 1; i >= 0; i--)
        for (int j = n - 1; j >= 0; j--) {
            int mul = (num1[i]-'0') * (num2[j]-'0');
            // 乘积在 res 对应的索引位置
            int p1 = i + j, p2 = i + j + 1;
            // 叠加到 res 上
            int sum = mul + res[p2];
            res[p2] = sum % 10;
            res[p1] += sum / 10;
        }
    // 结果前缀可能存的 0(未使用的位)
    int i = 0;
    while (i < res.size() && res[i] == 0)
        i++;
    // 将计算结果转化成字符串
    string str;
    for (; i < res.size(); i++)
        str.push_back('0' + res[i]);

    return str.size() == 0 ? "0" : str;
}

至此,字符串乘法算法就完成了。

PS:我认真写了 100 多篇原创,手把手刷 200 道力扣题目,所有发布在 labuladong的算法小抄,持续更新。建议收藏,按照个人文章顺序刷题,掌握各类算法套路后投再入题海就如鱼得水了。

总结一下,咱们习觉得常的一些思惟方式,在计算机看来是很是难以作到的。好比说咱们习惯的算术流程并不复杂,可是若是让你再进一步,翻译成代码逻辑,并不简单。算法须要将计算流程再简化,经过边算边叠加的方式来获得结果。

俗话教育咱们,不要陷入思惟定式,不要程序化,要发散思惟,要创新。但我以为程序化并非坏事,能够大幅提升效率,减少失误率。算法不就是一套程序化的思惟吗,只有程序化才能让计算机帮助咱们解决复杂问题呀!

也许算法就是一种寻找思惟定式的思惟吧,但愿本文对你有帮助。

_____________

相关文章
相关标签/搜索