diff --git a/divide_and_conquer/karatsuba_algorithm_for_fast_multiplication.cpp b/divide_and_conquer/karatsuba_algorithm_for_fast_multiplication.cpp index dc8b67b19..d931335cc 100644 --- a/divide_and_conquer/karatsuba_algorithm_for_fast_multiplication.cpp +++ b/divide_and_conquer/karatsuba_algorithm_for_fast_multiplication.cpp @@ -1,17 +1,20 @@ /** * @file - * @brief Implementation of the [Karatsuba algorithm for fast multiplication](https://en.wikipedia.org/wiki/Karatsuba_algorithm) + * @brief Implementation of the [Karatsuba algorithm for fast + * multiplication](https://en.wikipedia.org/wiki/Karatsuba_algorithm) * @details - * Given two strings in binary notation we want to multiply them and return the value - * Simple approach is to multiply bits one by one which will give the time complexity of - * around O(n^2). To make it more efficient we will be using Karatsuba' algorithm to find the product which will solve the problem O(nlogn) of time. + * Given two strings in binary notation we want to multiply them and return the + * value Simple approach is to multiply bits one by one which will give the time + * complexity of around O(n^2). To make it more efficient we will be using + * Karatsuba' algorithm to find the product which will solve the problem + * O(nlogn) of time. * @author [Swastika Gupta](https://github.com/Swastyy) */ #include /// for assert +#include /// for string #include /// for IO operations #include /// for std::vector -#include /// for string /** * @namespace divide_and_conquer @@ -20,57 +23,59 @@ namespace divide_and_conquer { /** * @namespace karatsuba_algorithm - * @brief Functions for the [Karatsuba algorithm for fast multiplication](https://en.wikipedia.org/wiki/Karatsuba_algorithm) + * @brief Functions for the [Karatsuba algorithm for fast + * multiplication](https://en.wikipedia.org/wiki/Karatsuba_algorithm) */ namespace karatsuba_algorithm { /** - * @brief Helper function for the main function, that implements Karatsuba's algorithm for fast multiplication + * @brief Helper function for the main function, that implements Karatsuba's + * algorithm for fast multiplication * @param first the input string 1 * @param second the input string 2 * @returns the concatenated string */ -std::string addStrings( std::string first, std::string second ) -{ +std::string addStrings(std::string first, std::string second) { std::string result; // To store the resulting sum bits - + int64_t len1 = first.size(); int64_t len2 = second.size(); - int64_t length = std::max(len1,len2); + int64_t length = std::max(len1, len2); std::string zero = "0"; - if (len1 < len2) // make the string lengths equal + if (len1 < len2) // make the string lengths equal { - for (int64_t i = 0 ; i < len2 - len1 ; i++) { + for (int64_t i = 0; i < len2 - len1; i++) { zero += first; first = zero; } - } - else if (len1 > len2) - { + } else if (len1 > len2) { zero = "0"; - for (int64_t i = 0 ; i < len1 - len2 ; i++) { + for (int64_t i = 0; i < len1 - len2; i++) { zero += second; second = zero; } } - int64_t carry = 0; - for (int64_t i = length-1 ; i >= 0 ; i--) { + int64_t carry = 0; + for (int64_t i = length - 1; i >= 0; i--) { int64_t firstBit = first.at(i) - '0'; int64_t secondBit = second.at(i) - '0'; - - int64_t sum = (firstBit ^ secondBit ^ carry)+'0'; // sum of 3 bits + + int64_t sum = (firstBit ^ secondBit ^ carry) + '0'; // sum of 3 bits std::string temp; temp = std::to_string(sum); temp += result; result = temp; - - carry = (firstBit&secondBit) | (secondBit&carry) | (firstBit&carry); // sum of 3 bits + + carry = (firstBit & secondBit) | (secondBit & carry) | + (firstBit & carry); // sum of 3 bits } - - if(carry) result = '1' + result; // adding 1 incase of overflow + + if (carry) + result = '1' + result; // adding 1 incase of overflow return result; } /** - * @brief The main function implements Karatsuba's algorithm for fast multiplication + * @brief The main function implements Karatsuba's algorithm for fast + * multiplication * @param str1 the input string 1 * @param str2 the input string 2 * @returns the multiplicative number value @@ -78,40 +83,43 @@ std::string addStrings( std::string first, std::string second ) int64_t karatsuba_algorithm(std::string str1, std::string str2) { int64_t len1 = str1.size(); int64_t len2 = str2.size(); - int64_t n = std::max(len1,len2); + int64_t n = std::max(len1, len2); std::string zero = "0"; - if (len1 < len2) - { - for (int64_t i = 0 ; i < len2 - len1 ; i++) { + if (len1 < len2) { + for (int64_t i = 0; i < len2 - len1; i++) { zero += str1; str1 = zero; } - } - else if (len1 > len2) - { + } else if (len1 > len2) { zero = "0"; - for (int64_t i = 0 ; i < len1 - len2 ; i++) { + for (int64_t i = 0; i < len1 - len2; i++) { zero += str2; str2 = zero; } } - if(n==0) return 0; - if(n==1) return (str1[0] - '0')*(str2[0] - '0'); - int64_t fh = n/2; // first half of string - int64_t sh = (n-fh); // second half of string - - std::string Xl = str1.substr(0, fh); // first half of first string - std::string Xr = str1.substr(fh, sh); // second half of first string - - std::string Yl = str2.substr(0, fh); // first half of second string - std::string Yr = str2.substr(fh, sh); // second half of second string - + if (n == 0) + return 0; + if (n == 1) + return (str1[0] - '0') * (str2[0] - '0'); + int64_t fh = n / 2; // first half of string + int64_t sh = (n - fh); // second half of string + + std::string Xl = str1.substr(0, fh); // first half of first string + std::string Xr = str1.substr(fh, sh); // second half of first string + + std::string Yl = str2.substr(0, fh); // first half of second string + std::string Yr = str2.substr(fh, sh); // second half of second string + // Calculating the three products of inputs of size n/2 recursively int64_t product1 = karatsuba_algorithm(Xl, Yl); int64_t product2 = karatsuba_algorithm(Xr, Yr); - int64_t product3 = karatsuba_algorithm(divide_and_conquer::karatsuba_algorithm::addStrings(Xl, Xr), divide_and_conquer::karatsuba_algorithm::addStrings(Yl, Yr)); - - return product1*(1<<(2*sh)) + (product3 - product1 - product2)*(1<