85 lines
2.4 KiB
Rust
85 lines
2.4 KiB
Rust
use std::cmp;
|
|
|
|
pub 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::<i64>().unwrap() * y.parse::<i64>().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::<Vec<char>>();
|
|
let y_chars_rev = y.chars().rev().collect::<Vec<char>>();
|
|
|
|
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::<Vec<char>>()[start_index as usize..]
|
|
.iter()
|
|
.collect()
|
|
}
|
|
}
|
|
}
|