diff --git a/43_multiply_strings/Cargo.lock b/43_multiply_strings/Cargo.lock new file mode 100644 index 0000000..27c6c9e --- /dev/null +++ b/43_multiply_strings/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "multiply_strings" +version = "0.1.0" diff --git a/43_multiply_strings/Cargo.toml b/43_multiply_strings/Cargo.toml new file mode 100644 index 0000000..615461e --- /dev/null +++ b/43_multiply_strings/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "multiply_strings" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/43_multiply_strings/src/main.rs b/43_multiply_strings/src/main.rs new file mode 100644 index 0000000..21fc508 --- /dev/null +++ b/43_multiply_strings/src/main.rs @@ -0,0 +1,90 @@ +use std::cmp; + +fn main() { + let x = "000".to_string(); + let y = "0".to_string(); + println!("{}", Solution::plus(x, y)); +} + +struct Solution; + +impl Solution { + pub fn multiply(x: String, y: String) -> String { + Solution::karatsuba(&x, &y) + } + + fn karatsuba(x: &str, y: &str) -> String { + if x.len() <= 9 && y.len() <= 9 { + return (x.parse::().unwrap() * y.parse::().unwrap()).to_string(); + } + + let len = cmp::max(x.len(), y.len()); + let len_half = len / 2; + + let mut x_string = x.to_string(); + if x.len() < len { + let zeros = "0".repeat(len - x.len()); + x_string = zeros + &x; + } + let mut y_string = y.to_string(); + if y.len() < len { + let zeros = "0".repeat(len - y.len()); + y_string = zeros + &y; + } + + let x1 = &x_string[..len_half]; + let x2 = &x_string[len_half..]; + let y1 = &y_string[..len_half]; + let y2 = &y_string[len_half..]; + + let a = Solution::karatsuba(x1, y1); + let b = Solution::karatsuba(x2, y2); + let c = Solution::karatsuba(x1, y2); + let d = Solution::karatsuba(x2, y1); + + let result = Solution::plus(a + &"0".repeat((len - len_half) * 2), b); + let result = Solution::plus(result, c + &"0".repeat(len - len_half)); + let result = Solution::plus(result, d + &"0".repeat(len - len_half)); + + result + } + + fn plus(x: String, y: String) -> String { + let len = cmp::max(x.len(), y.len()); + + let x_chars_rev = x.chars().rev().collect::>(); + let y_chars_rev = y.chars().rev().collect::>(); + + let mut carry = 0; + let mut result = String::new(); + + for i in 0..len { + let xn = if i < x.len() { x_chars_rev[i] } else { '0' } as i32 - 48; + let yn = if i < y.len() { y_chars_rev[i] } else { '0' } as i32 - 48; + + let sum = xn + yn + carry; + carry = sum / 10; + result.push_str(&(sum % 10).to_string()); + } + + if carry > 0 { + result.push_str(&carry.to_string()); + } + + let mut start_index = -1; + for (i, c) in result.chars().rev().enumerate() { + if c != '0' { + start_index = i as i32; + break; + } + } + + if start_index < 0 { + "0".to_string() + } else { + result.chars().rev().collect::>()[start_index as usize..] + .iter() + .collect() + } + } +}