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
 

Functions

std::string divide_and_conquer::karatsuba_algorithm::addStrings (std::string first, std::string second)
 Helper function for the main function, that implements Karatsuba's algorithm for fast multiplication. More...
 
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. More...
 
static void test ()
 Self-test implementations. More...
 
int main ()
 Main function. More...
 

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

Function Documentation

◆ addStrings()

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

Helper function for the main function, that implements Karatsuba's algorithm for fast multiplication.

Parameters
firstthe input string 1
secondthe input string 2
Returns
the concatenated string
37 {
38 std::string result; // To store the resulting sum bits
39
40 int64_t len1 = first.size();
41 int64_t len2 = second.size();
42 int64_t length = std::max(len1, len2);
43 std::string zero = "0";
44 if (len1 < len2) // make the string lengths equal
45 {
46 for (int64_t i = 0; i < len2 - len1; i++) {
47 zero += first;
48 first = zero;
49 }
50 } else if (len1 > len2) {
51 zero = "0";
52 for (int64_t i = 0; i < len1 - len2; i++) {
53 zero += second;
54 second = zero;
55 }
56 }
57 int64_t carry = 0;
58 for (int64_t i = length - 1; i >= 0; i--) {
59 int64_t firstBit = first.at(i) - '0';
60 int64_t secondBit = second.at(i) - '0';
61
62 int64_t sum = (firstBit ^ secondBit ^ carry) + '0'; // sum of 3 bits
63 std::string temp;
64 temp = std::to_string(sum);
65 temp += result;
66 result = temp;
67
68 carry = (firstBit & secondBit) | (secondBit & carry) |
69 (firstBit & carry); // sum of 3 bits
70 }
71
72 if (carry) {
73 result = '1' + result; // adding 1 incase of overflow
74 }
75 return result;
76}
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)
T to_string(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 multiplicative number value
84 {
85 int64_t len1 = str1.size();
86 int64_t len2 = str2.size();
87 int64_t n = std::max(len1, len2);
88 std::string zero = "0";
89 if (len1 < len2) {
90 for (int64_t i = 0; i < len2 - len1; i++) {
91 zero += str1;
92 str1 = zero;
93 }
94 } else if (len1 > len2) {
95 zero = "0";
96 for (int64_t i = 0; i < len1 - len2; i++) {
97 zero += str2;
98 str2 = zero;
99 }
100 }
101 if (n == 0) {
102 return 0;
103 }
104 if (n == 1) {
105 return (str1[0] - '0') * (str2[0] - '0');
106 }
107 int64_t fh = n / 2; // first half of string
108 int64_t sh = (n - fh); // second half of string
109
110 std::string Xl = str1.substr(0, fh); // first half of first string
111 std::string Xr = str1.substr(fh, sh); // second half of first string
112
113 std::string Yl = str2.substr(0, fh); // first half of second string
114 std::string Yr = str2.substr(fh, sh); // second half of second string
115
116 // Calculating the three products of inputs of size n/2 recursively
117 int64_t product1 = karatsuba_algorithm(Xl, Yl);
118 int64_t product2 = karatsuba_algorithm(Xr, Yr);
119 int64_t product3 = karatsuba_algorithm(
120 divide_and_conquer::karatsuba_algorithm::addStrings(Xl, Xr),
121 divide_and_conquer::karatsuba_algorithm::addStrings(Yl, Yr));
122
123 return product1 * (1 << (2 * sh)) +
124 (product3 - product1 - product2) * (1 << sh) +
125 product2; // combining the three products to get the final result.
126}
Functions for the Karatsuba algorithm for fast multiplication
T substr(T... args)
Here is the call graph for this function:

◆ main()

int main ( void  )

Main function.

Returns
0 on exit
164 {
165 test(); // run self-test implementations
166 return 0;
167}
static void test()
Self-test implementations.
Definition: karatsuba_algorithm_for_fast_multiplication.cpp:134
Here is the call graph for this function:

◆ test()

static void test ( )
static

Self-test implementations.

Returns
void
134 {
135 // 1st test
136 std::string s11 = "1";
137 std::string s12 = "1010";
138 std::cout << "1st test... ";
139 assert(divide_and_conquer::karatsuba_algorithm::karatsuba_algorithm(
140 s11, s12) == 10); // here the multiplication is 10
141 std::cout << "passed" << std::endl;
142
143 // 2nd test
144 std::string s21 = "11";
145 std::string s22 = "1010";
146 std::cout << "2nd test... ";
147 assert(divide_and_conquer::karatsuba_algorithm::karatsuba_algorithm(
148 s21, s22) == 30); // here the multiplication is 30
149 std::cout << "passed" << std::endl;
150
151 // 3rd test
152 std::string s31 = "110";
153 std::string s32 = "1010";
154 std::cout << "3rd test... ";
155 assert(divide_and_conquer::karatsuba_algorithm::karatsuba_algorithm(
156 s31, s32) == 60); // here the multiplication is 60
157 std::cout << "passed" << std::endl;
158}
T endl(T... args)
Here is the call graph for this function: