Algorithms_in_C++ 1.0.0
Set of algorithms implemented in C++.
Loading...
Searching...
No Matches
karatsuba_algorithm_for_fast_multiplication.cpp File Reference

Implementation of the Karatsuba algorithm for fast multiplication More...

#include <cassert>
#include <cstring>
#include <iostream>
#include <vector>
Include dependency graph for karatsuba_algorithm_for_fast_multiplication.cpp:

Namespaces

namespace  divide_and_conquer
 for std::vector
 
namespace  karatsuba_algorithm
 Functions for the Karatsuba algorithm for fast multiplication implementation.
 

Functions

std::string divide_and_conquer::karatsuba_algorithm::add_strings (std::string first, std::string second)
 Binary addition.
 
std::string divide_and_conquer::karatsuba_algorithm::safe_substr (const std::string &str, int64_t x1, int64_t x2, int64_t n)
 Wrapper function for substr that considers leading zeros.
 
int64_t divide_and_conquer::karatsuba_algorithm::karatsuba_algorithm (std::string str1, std::string str2)
 The main function implements Karatsuba's algorithm for fast multiplication.
 
static void test ()
 Self-test implementations.
 
int main ()
 Main function.
 

Detailed Description

Implementation of the Karatsuba algorithm for fast multiplication

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
Ameer Carlo Lubang

Function Documentation

◆ add_strings()

std::string divide_and_conquer::karatsuba_algorithm::add_strings ( std::string first,
std::string second )

Binary addition.

Parameters
first,theinput string 1
second,theinput string 2
Returns
the sum binary string
37 {
38 std::string result; // to store the resulting sum bits
39
40 // make the string lengths equal
41 int64_t len1 = first.size();
42 int64_t len2 = second.size();
43 std::string zero = "0";
44 if (len1 < len2) {
45 for (int64_t i = 0; i < len2 - len1; i++) {
46 zero += first;
47 first = zero;
48 zero = "0"; // Prevents CI from failing
49 }
50 } else if (len1 > len2) {
51 for (int64_t i = 0; i < len1 - len2; i++) {
52 zero += second;
53 second = zero;
54 zero = "0"; // Prevents CI from failing
55 }
56 }
57
58 int64_t length = std::max(len1, len2);
59 int64_t carry = 0;
60 for (int64_t i = length - 1; i >= 0; i--) {
61 int64_t firstBit = first.at(i) - '0';
62 int64_t secondBit = second.at(i) - '0';
63
64 int64_t sum = (char(firstBit ^ secondBit ^ carry)) + '0'; // sum of 3 bits
65 result.insert(result.begin(), sum);
66
67 carry = char((firstBit & secondBit) | (secondBit & carry) |
68 (firstBit & carry)); // sum of 3 bits
69 }
70
71 if (carry) {
72 result.insert(result.begin(), '1'); // adding 1 incase of overflow
73 }
74 return result;
75}
T at(T... args)
uint64_t result(uint64_t n)
Definition fibonacci_sum.cpp:76
T max(T... args)
T sum(const std::vector< std::valarray< T > > &A)
Definition vector_ops.hpp:232
T size(T... args)
Here is the call graph for this function:

◆ karatsuba_algorithm()

int64_t divide_and_conquer::karatsuba_algorithm::karatsuba_algorithm ( std::string str1,
std::string str2 )

The main function implements Karatsuba's algorithm for fast multiplication.

Parameters
str1the input string 1
str2the input string 2
Returns
the product number value
112 {
113 int64_t len1 = str1.size();
114 int64_t len2 = str2.size();
115 int64_t n = std::max(len1, len2);
116
117 if (n == 0) {
118 return 0;
119 }
120 if (n == 1) {
121 return (str1[0] - '0') * (str2[0] - '0');
122 }
123
124 int64_t fh = n / 2; // first half of string
125 int64_t sh = n - fh; // second half of string
126
127 std::string Xl = divide_and_conquer::karatsuba_algorithm::safe_substr(str1, 0, fh, n); // first half of first string
128 std::string Xr = divide_and_conquer::karatsuba_algorithm::safe_substr(str1, fh, sh, n); // second half of first string
129
130 std::string Yl = divide_and_conquer::karatsuba_algorithm::safe_substr(str2, 0, fh, n); // first half of second string
131 std::string Yr = divide_and_conquer::karatsuba_algorithm::safe_substr(str2, fh, sh, n); // second half of second string
132
133 // calculating the three products of inputs of size n/2 recursively
134 int64_t product1 = karatsuba_algorithm(Xl, Yl);
135 int64_t product2 = karatsuba_algorithm(Xr, Yr);
136 int64_t product3 = karatsuba_algorithm(
137 divide_and_conquer::karatsuba_algorithm::add_strings(Xl, Xr),
138 divide_and_conquer::karatsuba_algorithm::add_strings(Yl, Yr));
139
140 return product1 * (1 << (2 * sh)) +
141 (product3 - product1 - product2) * (1 << sh) +
142 product2; // combining the three products to get the final result.
143}
std::string safe_substr(const std::string &str, int64_t x1, int64_t x2, int64_t n)
Wrapper function for substr that considers leading zeros.
Definition karatsuba_algorithm_for_fast_multiplication.cpp:86
Functions for the Karatsuba algorithm for fast multiplication implementation.
Here is the call graph for this function:

◆ main()

int main ( void )

Main function.

Returns
0 on exit
181 {
182 test(); // run self-test implementations
183 return 0;
184}
static void test()
Self-test implementations.
Definition karatsuba_algorithm_for_fast_multiplication.cpp:151
Here is the call graph for this function:

◆ safe_substr()

std::string divide_and_conquer::karatsuba_algorithm::safe_substr ( const std::string & str,
int64_t x1,
int64_t x2,
int64_t n )

Wrapper function for substr that considers leading zeros.

Parameters
str,thebinary input string.
x1,thesubstr parameter integer 1
x2,thesubstr parameter integer 2
n,isthe length of the "whole" string: leading zeros + str
Returns
the "safe" substring for the algorithm without leading zeros
"0" if substring spans to leading zeros only
86 {
87 int64_t len = str.size();
88
89 if (len >= n) {
90 return str.substr(x1, x2);
91 }
92
93 int64_t y1 = x1 - (n - len); // index in str of first char of substring of "whole" string
94 int64_t y2 = (x1 + x2 - 1) - (n - len); // index in str of last char of substring of "whole" string
95
96 if (y2 < 0) {
97 return "0";
98 } else if (y1 < 0) {
99 return str.substr(0, y2 + 1);
100 } else {
101 return str.substr(y1, x2);
102 }
103}
T substr(T... args)
Here is the call graph for this function:

◆ test()

static void test ( )
static

Self-test implementations.

Returns
void
151 {
152 // 1st test
153 std::string s11 = "1"; // 1
154 std::string s12 = "1010"; // 10
155 std::cout << "1st test... ";
156 assert(divide_and_conquer::karatsuba_algorithm::karatsuba_algorithm(
157 s11, s12) == 10);
158 std::cout << "passed" << std::endl;
159
160 // 2nd test
161 std::string s21 = "11"; // 3
162 std::string s22 = "1010"; // 10
163 std::cout << "2nd test... ";
164 assert(divide_and_conquer::karatsuba_algorithm::karatsuba_algorithm(
165 s21, s22) == 30);
166 std::cout << "passed" << std::endl;
167
168 // 3rd test
169 std::string s31 = "110"; // 6
170 std::string s32 = "1010"; // 10
171 std::cout << "3rd test... ";
172 assert(divide_and_conquer::karatsuba_algorithm::karatsuba_algorithm(
173 s31, s32) == 60);
174 std::cout << "passed" << std::endl;
175}
T endl(T... args)
Here is the call graph for this function: