C++字串乘法


我們有兩個由整陣列成的字串,長度最多為200。這兩個字串都不包含任何前導0,但數字本身可以是0。我們需要對整數字符串進行乘法運算,因此需要找到一個解決方案。讓我們看看如何更輕鬆地解決這個問題。

假設我們有兩個表示數字的字串。我們需要將它們相乘並返回結果,結果也以字串形式表示。例如,如果數字是“26”和“12”,則結果將是“312”。以下是幾種在C++中進行字串乘法的方法。

使用`stoll()`方法

在本節中,我們將學習如何使用內建方法在C++中將兩個字串相乘。雖然這不是一種高效的方法,因為大型整數可能導致潛在的溢位,但我們仍然介紹這種方法,以便全面瞭解此方法。

以下是使用`stoll()`在C++中將兩個字串相乘的程式碼

#include <iostream>
#include <string>
using namespace std;
class Solution {
public:
   string multiply(string num1, string num2) {
   long long n1 = stoll(num1);
   long long n2 = stoll(num2);
   long long res = n1 * n2;
   return to_string(res);
   }
};
int main() {
   Solution sol;
   cout << sol.multiply("123", "456") << endl;  // Output: 56088
   return 0;
}

時間複雜度:O(1)

空間複雜度:O(1)

解釋

在這個解決方案中,給定兩個字串num1num2,我們需要將它們轉換為整數。為此,初始化兩個long型別的變數n1n2,分別為它們賦值字串num1num2的整數值。然後,將n1n2的乘法結果儲存在一個名為reslong long型別的變數中,並以字串的形式返回它。

注意:此方法不適用於大型輸入

透過相乘每一位

為了解決這個問題,我們將遵循以下步驟

  • 初始化結果字串ans,其長度為m+n,其中m是第一個給定字串的長度,n是第二個給定字串的長度,並將值設定為'0'。
  • 從右到左遍歷num1和num2字串。對於每個num1數字,將其乘以每個num2數字。
  • 將上一步的乘法結果新增到ans的適當位置。
  • 調整進位,如果存在進位,則將其新增到字串中下一個較高的位置。
  • 如果存在前導零,則刪除字串中的前導零。
  • 最後返回ans字串。如果ans字串只包含0,則返回“0”。

下面是一個示例程式碼,用於解決C++中將兩個字串相乘的問題

#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
   string multiply(string num1, string num2);
};
string Solution::multiply(string nums1, string nums2) {
   int n = nums1.size();
   int m = nums2.size();
   string ans(n + m, '0');
   for(int i = n - 1; i >= 0; i--) {
      for(int j = m - 1; j >= 0; j--) {
         int p = (nums1[i] - '0') * (nums2[j] - '0') + (ans[i + j + 1] - '0');
         ans[i+j+1] = p % 10 + '0';
         ans[i+j] += p / 10;
   }
}
   for(int i = 0; i < m + n; i++) {
      if(ans[i] !='0') return ans.substr(i);
   }
   return "0";
   }
int main() {
   Solution ob;
   cout << ob.multiply("28", "25");
   return 0;
}

時間複雜度:O(n * m)

空間複雜度:O(n + m)

解釋

在這個示例程式碼中,我們從右到左遍歷num1num2字串,並將兩個字串的最後一位數字相乘,並將結果儲存在ans中,並將進位儲存在ans的下一個位置,並將其新增到下一個數字的乘積中。最後,我們返回ans

Karatsuba乘法演算法

為了解決這個問題,我們將遵循以下步驟

  • 將給定的數字分成兩半。對於xy,讓x分成x1x0y分成y1y0
  • 使用遞迴計算三個乘積
    • A = multiply(x1, y1)
    • B = multiply(x0, y0)
    • C = multiply(x1 + x0, y1 + y0) - A - B
  • 使用以下公式組合結果
    • result = A * 10^2m + C * 10^m + B
  • 最後,返回組合的結果。

以下是一個示例 -

#include <bits/stdc++.h>
using namespace std;

class Solution {
public:
   string multiply(string x, string y);
private:
   string karatsuba(string x, string y);
   string add(string a, string b);
   string sub(string a, string b);
   string mulSingle(char x, char y);
};

string Solution::multiply(string x, string y) {
   return karatsuba(x, y);
}

string Solution::karatsuba(string x, string y) {
   int n = max(x.size(), y.size());
   if (n == 0) return "0";
   if (n == 1) return mulSingle(x[0], y[0]);

   // Ensure both numbers have the same length
   while (x.size() < n) x = '0' + x;
   while (y.size() < n) y = '0' + y;

   int half = n / 2;
   string x1 = x.substr(0, half);
   string x0 = x.substr(half);
   string y1 = y.substr(0, half);
   string y0 = y.substr(half);

   string A = karatsuba(x1, y1);
   string B = karatsuba(x0, y0);
   string C = karatsuba(add(x1, x0), add(y1, y0));
   C = sub(C, add(A, B));

   return add(add(A + string(2 * (n - half), '0'), C + string(n - half, '0')), B);
}

string Solution::add(string a, string b) {
   int carry = 0;
   string res = "";
   int i = a.size() - 1, j = b.size() - 1;
   while (i >= 0 || j >= 0 || carry) {
      int sum = carry;
      if (i >= 0) sum += a[i--] - '0';
      if (j >= 0) sum += b[j--] - '0';
      carry = sum / 10;
      res += (sum % 10) + '0';
   }
   reverse(res.begin(), res.end());
   return res;
}

string Solution::sub(string a, string b) {
   // Assumes a >= b
   int borrow = 0;
   string res = "";
   int i = a.size() - 1, j = b.size() - 1;
   while (i >= 0 || j >= 0 || borrow) {
      int diff = (i >= 0 ? a[i--] - '0' : 0) - (j >= 0 ? b[j--] - '0' : 0) - borrow;
      if (diff < 0) {
         diff += 10;
         borrow = 1;
      } else {
         borrow = 0;
      }
      res += diff + '0';
   }
   reverse(res.begin(), res.end());
   return res;
}

string Solution::mulSingle(char x, char y) {
   return to_string((x - '0') * (y - '0'));
}

int main() {
   Solution ob;
   cout << ob.multiply("1234", "5678");
}

時間複雜度:O(n^1.585)

空間複雜度:O(1)

解釋

在這個示例程式碼中,我們將每個數字分成兩半,然後使用遞迴計算三個乘積:ABC。然後,我們使用提供的公式組合這些乘積以獲得最終結果。這種方法透過將乘法分解成更小的子問題來降低乘法的複雜度,對於大數而言,這種方法效率更高。

更新於:2024年11月11日

7K+ 次瀏覽

開啟你的職業生涯

完成課程獲得認證

開始學習
廣告