关于算法:字符串乘法

50次阅读

共计 1442 个字符,预计需要花费 4 分钟才能阅读完成。

读完本文,你能够去力扣拿下如下题目:

43. 字符串相乘

———–

对于比拟小的数字,做运算能够间接应用编程语言提供的运算符,然而如果相乘的两个因数十分大,语言提供的数据类型可能就会溢出。一种代替计划就是,运算数以字符串的模式输出,而后模拟咱们小学学习的乘法算术过程计算出后果,并且也用字符串示意。

须要留神的是,num1num2 能够十分长,所以不能够把他们间接转成整型而后运算,惟一的思路就是模拟咱们手算乘法。

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

计算 123 × 5,再计算 123 × 4,最初错一位相加。这个流程恐怕小学生都能够纯熟实现,然而你是否能 把这个运算过程进一步机械化,写成一套算法指令让没有任何智商的计算机来执行呢?

你看这个简略过程,其中波及乘法进位,波及错位相加,还波及加法进位;而且还有一些不易觉察的问题,比如说两位数乘以两位数,后果可能是四位数,也可能是三位数,你怎么想出一个标准化的解决形式?这就是算法的魅力,如果没有计算机思维,简略的问题可能都没方法自动化解决。

首先,咱们这种手算形式还是太「高级」了,咱们要再「低级」一点,123 × 5123 × 4 的过程还能够进一步合成,最初再相加:

当初 123 并不大,如果是个很大的数字的话,是无奈间接计算乘积的。咱们能够用一个数组在底下接管相加后果:

整个计算过程大略是这样,有两个指针 i,jnum1num2 上游走,计算乘积,同时将乘积叠加到 res 的正确地位

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

其实,仔细察看之后就发现,num1[i]num2[j] 的乘积对应的就是 res[i+j]res[i+j+1] 这两个地位

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

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;}

至此,字符串乘法算法就实现了。

总结一下,咱们司空见惯的一些思维形式,在计算机看来是十分难以做到的。比如说咱们习惯的算术流程并不简单,然而如果让你再进一步,翻译成代码逻辑,并不简略。算法须要将计算流程再简化,通过边算边叠加的形式来失去后果。

俗话教育咱们,不要陷入思维定式,不要程序化,要发散思维,要翻新。但我感觉程序化并不是好事,能够大幅提高效率,减小失误率。算法不就是一套程序化的思维吗,只有程序化能力让计算机帮忙咱们解决简单问题呀!

兴许算法就是一种 寻找思维定式的思维 吧,心愿本文对你有帮忙。

正文完
 0