字符串乘法

對於比較小的數字,作運算能夠直接使用編程語言提供的運算符,可是若是相乘的兩個因數很是大,語言提供的數據類型可能就會溢出。一種替代方案就是,運算數以字符串的形式輸入,而後模仿咱們小學學習的乘法算術過程計算出結果,而且也用字符串表示。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的算法小抄,持續更新。建議收藏,按照個人文章順序刷題,掌握各類算法套路後投再入題海就如魚得水了。

總結一下,咱們習覺得常的一些思惟方式,在計算機看來是很是難以作到的。好比說咱們習慣的算術流程並不複雜,可是若是讓你再進一步,翻譯成代碼邏輯,並不簡單。算法須要將計算流程再簡化,經過邊算邊疊加的方式來獲得結果。

俗話教育咱們,不要陷入思惟定式,不要程序化,要發散思惟,要創新。但我以爲程序化並非壞事,能夠大幅提升效率,減少失誤率。算法不就是一套程序化的思惟嗎,只有程序化才能讓計算機幫助咱們解決複雜問題呀!

也許算法就是一種尋找思惟定式的思惟吧,但願本文對你有幫助。

_____________

相關文章
相關標籤/搜索