a
a
algo-en
english
Search
K

# String Multiplication

Translator: youyun
For relatively small numbers, you can calculate directly using the operators provided by a programming language. When the numbers become very big, the default data types might overflow. An alternative way is to use string to represent the numbers, perform the multiplication in the primary school way, and produce the result as string as well. Take this question as an example. Note that both `num1` and `num2` can be very long. We can't directly calculate by transforming them to integers. We can learn from the process multiplying by hand.
For example, when we multiply `123 × 45` by hand, the process is shown in the following diagram: Firstly, calculate `123 × 5`. Then calculate `123 × 4`. In the end, add them together by shifting one digit. We learned this method in primary school. Can we generalize the steps in this process, such that a computer can understand?
This simple process actually involves a lot of knowledge - carry of multiplication, carry of addition, and adding numbers by shifting digits. Another not so obvious issue is the number of digits of the final result. When two two-digit numbers multiply, the result can be either four-digit or three-digit. How to generalize this? Without the mindset of a computer, we can't even automate simple problems. This is the beauty of algorithms.
Well, this process is still too high-level. Let's try something at a lower level. The processes of `123 × 5` and `123 × 4` can be further broken into parts and add together: `123` is pretty small. If the number is large, we can't get the product directly. An array can help to store the result of addition: Here is the rough process of calculation. Two pointers `i, j` moves at `num1` and `num2` to multiply, adding the products to the correct positions of `res`: There is a key question now. How to add products to the correct positions of `res`? In other words, how to use `i, j` to calculate the corresponding indices in `res`?
With careful observation, the product of `num1[i]` and `num2[j]` corresponds to `res[i+j]` and `res[i+j+1]`. If we understand the above, we should be able to translate the process into code:
string multiply(string num1, string num2) {
int m = num1.size(), n = num2.size();
// the max number of digits in result is m + n
vector<int> res(m + n, 0);
// multiply from the rightmost digit
for (int i = m - 1; i >= 0; i--)
for (int j = n - 1; j >= 0; j--) {
int mul = (num1[i]-'0') * (num2[j]-'0');
// the corresponding index of product in res
int p1 = i + j, p2 = i + j + 1;
int sum = mul + res[p2];
res[p2] = sum % 10;
res[p1] += sum / 10;
}
// the result may have prefix of 0 (which is unused)
int i = 0;
while (i < res.size() && res[i] == 0)
i++;
// transform the result into string
string str;
for (; i < res.size(); i++)
str.push_back('0' + res[i]);
return str.size() == 0 ? "0" : str;
}
We have just completed the string multiplication.
In summary, some of our common ways of think may be hard to achieve by computer. For instance, the process of our calculation is not that complicated. But it is not easy to translate this process into code. Our algorithm needs to simplify the calculation process, achieve the result by adding while multiplying at the same time.
People usually say that we need to think out of the box, be creative, and be different. But systematic thinking can be a good thing. It can improve the efficiency and reduce the error rate. Algorithms are based on systematic thinking, and can help us to resolve complex problems.
Maybe algorithms are a kind of mindset to find a systematic thinking. Hope this article helps.