
Problem Statement
The task involves multiplying two numbers, given in string format, without directly converting them into integers or using large integer libraries. You will need to simulate the multiplication process that you would typically do by hand or using basic arithmetic algorithms because the strings can be up to 200 characters long. This process must return the product also as a string, ensuring compatibility with very large numbers that exceed typical integer support in most programming languages.
Examples
Example 1
Input:
num1 = "2", num2 = "3"
Output:
"6"
Example 2
Input:
num1 = "123", num2 = "456"
Output:
"56088"
Constraints
1 <= num1.length, num2.length <= 200
num1
andnum2
consist of digits only.- Both
num1
andnum2
do not contain any leading zero, except the number0
itself.
Approach and Intuition
To solve the problem of multiplying two large numbers provided as strings, the classic approach inspired by long multiplication (or grade-school multiplication) is used. This method can be intuitive when visualized as aligning numbers in a staggered format, multiplying digits in a pairwise manner from right to left, and keeping track of carry-over values.
Initial Setup:
- Identify the lengths of the two strings,
num1
andnum2
. - Create an array (or list) to hold the intermediate results, with a size that is the sum of the lengths of
num1
andnum2
. This array will store the sums of the products of digit pairs.
- Identify the lengths of the two strings,
Multiplying Each Digit:
- For each digit in
num1
and each digit innum2
, calculate the product. Since the characters represent digits, they need to be converted to integers for arithmetic operations. - Calculate the positions in the results array where the result of the product of two digits should be added.
- For each digit in
Handling Carry Over:
- Once all products are added to the result array, handle the carry for each position starting from the least significant position (the end of the array).
- Adjust each position to ensure it represents a single digit, transferring the excess to the next left position.
Building the Final Product String:
- Convert the result array back to a string. Be mindful of not including initial zeros except where the entire product results in zero.
- Consider edge cases, such as when one or both of the numbers are zero.
Using this algorithmic approach handles the constraints effectively, ensuring operation within the limits without running into performance or capacity issues typical integer operations might face. This method directly utilizes the positional notation system, which underlies decimal multiplication, adapting it for efficient computation even with extremely large numbers.
Solutions
- C++
- Java
- C
- JavaScript
- Python
class Solution {
public:
string multiplyStrings(string number1, string number2) {
if (number1 == "0" || number2 == "0") return "0";
reverse(number1.begin(), number1.end());
reverse(number2.begin(), number2.end());
int len = number1.size() + number2.size();
string result(len, '0');
for (int idx2 = 0; idx2 < number2.size(); idx2++) {
int digit2 = number2[idx2] - '0';
for (int idx1 = 0; idx1 < number1.size(); idx1++) {
int digit1 = number1[idx1] - '0';
int carry = result[idx1 + idx2] - '0';
int product = digit1 * digit2 + carry;
result[idx1 + idx2] = (product % 10) + '0';
result[idx1 + idx2 + 1] += (product / 10);
}
}
while (result.back() == '0' && result.length() > 1) result.pop_back();
reverse(result.begin(), result.end());
return result;
}
};
This implementation in C++ solves the problem of multiplying two numerical strings and returning the result as a string. Follow these steps in the multiplyStrings
function:
- Check if either of the input strings is "0". If yes, return "0" since multiplying by zero yields zero.
- Reverse both input strings to facilitate the multiplication from least significant to most significant digits.
- Define the result string with a maximum possible length of the combination of both input strings filled initially with '0'.
- Use two nested loops to iterate over each digit of both strings.
- In the outer loop, treat each character as a single digit from the second string starting from the least significant digit.
- In the inner loop, repeat the process for the first string.
- Multiply these two digits, and add the result to the corresponding position in the result string, taking care to handle carry-over between digits.
- After processing all digits, remove leading zeros from the result string except for the zero itself if the result is zero.
- Finally, reverse the result string back to its correct order and return it.
This method ensures that the multiplication handles very large numbers accurately by working with each digit individually and managing carry-over explicitly.
class StringMultiplier {
public String productStrings(String str1, String str2) {
if (str1.equals("0") || str2.equals("0")) {
return "0";
}
StringBuilder reversedStr1 = new StringBuilder(str1);
StringBuilder reversedStr2 = new StringBuilder(str2);
reversedStr1.reverse();
reversedStr2.reverse();
int lengthResult = reversedStr1.length() + reversedStr2.length();
StringBuilder result = new StringBuilder();
for (int i = 0; i < lengthResult; ++i) {
result.append(0);
}
for (int pos2 = 0; pos2 < reversedStr2.length(); pos2++) {
int digit2 = reversedStr2.charAt(pos2) - '0';
for (int pos1 = 0; pos1 < reversedStr1.length(); pos1++) {
int digit1 = reversedStr1.charAt(pos1) - '0';
int currentPos = pos1 + pos2;
int currentVal = result.charAt(currentPos) - '0';
int multResult = digit1 * digit2 + currentVal;
result.setCharAt(
currentPos,
(char) ((multResult % 10) + '0')
);
int nextVal = (result.charAt(currentPos + 1) - '0') + multResult / 10;
result.setCharAt(currentPos + 1, (char) (nextVal + '0'));
}
}
if (result.charAt(result.length() - 1) == '0') {
result.deleteCharAt(result.length() - 1);
}
result.reverse();
return result.toString();
}
}
The provided Java code defines a class StringMultiplier
that includes a method productStrings
to multiply two non-negative integer numbers represented as strings. This approach is particularly useful when working with values that exceed the range of standard numerical data types in programming languages.
The method productStrings
takes two string parameters str1
and str2
. If either string is "0," the product directly returns "0" to represent no multiplication needed. The algorithm employs the following key steps to compute the multiplication:
Each input string is reversed to facilitate the multiplication process from least significant to most significant digits.
An empty
StringBuilder
calledresult
is initialized to hold the intermediate and final results, sized to accommodate the maximum possible number of digits (sum of the lengths of the two strings).Nested loops iterate through each character (digit) of the reversed strings. The multiplication of corresponding digits (
digit1
anddigit2
) is calculated along with any carry from previous calculations.The products and carries are placed correctly in the
result
by updating the appropriate indices, handling the carry-over digits by adding and updating the next positions in the result.After completing the multiplication, leading zeros in the
result
are removed, and it is reversed to restore the correct order of digits.
Finally, result.toString()
converts the StringBuilder
to a string and returns it, which represents the product of the two input strings as a number in string format. This method efficiently handles large number calculations by manual digit manipulation, similar to traditional pen-and-paper multiplication, digit by digit.
char* reverse_string(char* s) {
int length = strlen(s); // Calculate the length of the string
int start, end;
char temp_char;
for (start = 0, end = length - 1; start < end; start++, end--) {
temp_char = s[start];
s[start] = s[end];
s[end] = temp_char; // Swap the characters
}
return s;
}
char* multiply_strings(char* num1, char* num2) {
if (strcmp(num1, "0") == 0 || strcmp(num2, "0") == 0) {
return "0";
}
reverse_string(num1); // Reverse the first number
reverse_string(num2); // Reverse the second number
int total_length = strlen(num1) + strlen(num2); // Sum of lengths of num1 and num2
char* result = (char*)calloc(total_length + 1, sizeof(char)); // Allocate space for the result
memset(result, '0', total_length); // Initialize all positions in result to '0'
for (int i = 0; i < strlen(num2); i++) {
int digit2 = num2[i] - '0';
for (int j = 0; j < strlen(num1); j++) {
int digit1 = num1[j] - '0';
int idx = i + j;
int carry = result[idx] - '0';
int prod = digit1 * digit2 + carry; // Calculate product plus carry
result[idx] = (prod % 10) + '0'; // Set current position in result
result[idx + 1] += (prod / 10); // Add carry to the next position
}
}
if (result[total_length - 1] == '0') {
result[total_length - 1] = '\0'; // Remove trailing zero if necessary
}
reverse_string(result); // Reverse the result back to normal order
return result;
}
Solution Summary:
The provided C code implements a function to multiply two numeric strings and returns the result as a string. This process efficiently handles multiplication without converting to numeric datatypes, making it suitable for numbers beyond standard integer limits. The function works by following these steps:
The
reverse_string(char* s)
function reverses the characters in the strings
. This reversal simplifies the multiplication process by aligning the least significant digits at the beginning of the string.The
multiply_strings(char* num1, char* num2)
function first checks if either of the string representations of the numbers is "0". If so, it returns "0" immediately, as the product will be zero.Both input strings,
num1
andnum2
, are reversed to position the least significant digit at the start.Memory is allocated dynamically for the result string, accounting for the maximum possible length, which is the sum of the lengths of
num1
andnum2
. All positions in the result array are initially set to '0'.Multiplication is carried out in a double loop. For each digit in
num2
, the function iterates through each digit innum1
, calculating the product of the current digits and adding this to a carry-over value stored in the result string. The process accounts for carry propagation immediately by adding and storing remainders and division results appropriately.Post multiplication, any trailing zero in the result is removed if the highest order position in the result array is '0'.
The resulting string is then reversed again to represent the correct number as its original order.
Finally, it returns the computed result as a string, achieving the multiplication of very large integers represented as strings.
This solution processes each digit individually and uses string manipulation to keep track of digits and carries, a method often used when dealing with high precision arithmetic or numbers exceeding typical data type limits in programming.
let multiplyStrings = function (str1, str2) {
if (str1 === "0" || str2 === "0") {
return "0";
}
let digits1 = [...str1];
let digits2 = [...str2];
// Reverse both arrays of digits
digits1.reverse();
digits2.reverse();
let maxLen = digits1.length + digits2.length;
let resultArr = new Array(maxLen).fill(0);
for (let idx2 = 0; idx2 < digits2.length; idx2++) {
let digitB = Number(digits2[idx2]);
for (let idx1 = 0; idx1 < digits1.length; idx1++) {
let digitA = Number(digits1[idx1]);
let position = idx1 + idx2;
let res = resultArr[position] + digitA * digitB;
resultArr[position] = res % 10;
resultArr[position + 1] += Math.floor(res / 10);
}
}
// Remove trailing zero
if (resultArr[resultArr.length - 1] == 0) {
resultArr.pop();
}
// Return the final multiplied string
resultArr.reverse();
return resultArr.join("");
};
The JavaScript solution provided multiplies two non-negative integer numbers represented as strings. This approach avoids the limitations of numerical operations in cases where the numbers exceed the maximum safe integer value in JavaScript. Here’s how the solution works:
Initial Check: If either string is
"0"
, the result is"0"
, since any number multiplied by zero is zero.Preparation:
- Convert the input strings
str1
andstr2
into arrays of characters, then reverse these arrays to facilitate the multiplication from least significant digit upwards.
- Convert the input strings
Setting Up the Result Array:
- Initialize an array
resultArr
to store the intermediate results with a length equal to the sum of lengths ofstr1
andstr2
, filled initially with zeros. This array will accommodate the largest possible number of digits that the multiplication might produce.
- Initialize an array
Multiplication Process:
- Iterate through each digit of
str2
usingidx2
, and for each digit instr2
, iterate through each digit ofstr1
usingidx1
. - For each pair of digits, calculate the product and add it to the corresponding index in
resultArr
. The index is determined by the sum of indicesidx1
andidx2
(position of the digit in the result). - Manage carrying over digits to the next position by adding the carry to the next index in
resultArr
.
- Iterate through each digit of
Cleanup:
- Before finishing, check the last element of
resultArr
; if it is zero (a leading zero), remove it. - Reverse
resultArr
to transform the result into the correct order.
- Before finishing, check the last element of
Result Compilation:
- Convert
resultArr
back into a string by joining its elements, forming the final product of the two input strings.
- Convert
This ensures that big numbers are accurately multiplied without overflow or precision errors related to JavaScript's number representation.
class Solution:
def multiply_strings(self, n1: str, n2: str) -> str:
if n1 == "0" or n2 == "0":
return "0"
# Length of product can at most be sum of lengths of n1 and n2.
length_total = len(n1) + len(n2)
result_digits = [0] * length_total
# Reverse both numbers for easier handling of digit multiplication
reversed_n1 = n1[::-1]
reversed_n2 = n2[::-1]
# Multiply each digit in reversed n2 with each digit in reversed n1
for index2, char2 in enumerate(reversed_n2):
for index1, char1 in enumerate(reversed_n1):
position = index1 + index2
multiplication_result = int(char1) * int(char2) + result_digits[position]
# Store the unit's place at the current position
result_digits[position] = multiplication_result % 10
# Carry over the ten's place to the next position
result_digits[position + 1] += multiplication_result // 10
# Remove trailing zero in result if present
if result_digits[-1] == 0:
result_digits.pop()
# Construct the final product string
return ''.join(map(str, result_digits[::-1]))
In the provided Python code, the problem of multiplying two non-negative integer strings is solved by simulating the multiplication process manually, without using direct numerical multiplication operations. This approach is particularly useful in situations where the numbers involved are so large that they might exceed the standard range of integer types in common programming languages.
The solution involves the following key steps:
- Check if either of the input strings is
"0"
. If so, return"0"
since any number multiplied by zero is zero. - Prepare an array
result_digits
to hold the result of the multiplication, initialized with zeros. The length of this array is the sum of lengths of the two input numbers, ensuring enough space to accommodate the largest possible product. - Reverse both input strings to facilitate easy digit-by-digit multiplication from the least significant to the most significant digits.
- Multiply each digit of the first number (reversed) by each digit of the second number (reversed), updating the
result_digits
array accordingly. This includes:- Calculating the current product and adding any existing value at the computed position.
- Storing the unit's place of the current product in the corresponding position.
- Carrying over the tens place to the next position in the
result_digits
array.
- After all multiplications are complete, any leading zero in the
result_digits
(which would now be at the end of the list due to the reversals) is removed. - The final result is constructed by reversing the
result_digits
list back and converting it to a string.
This method efficiently handles large numbers and performs multiplications digit by digit, mimicking the traditional paper-based multiplication method, which is robust and avoids issues related to integer overflow in programming languages.
No comments yet.