TheAlgorithms/C++
1.0.0
All the algorithms implemented in C++
Toggle main menu visibility
Loading...
Searching...
No Matches
karatsuba_algorithm_for_fast_multiplication.cpp
Go to the documentation of this file.
1
14
15
#include <cassert>
16
#include <cstring>
17
#include <iostream>
18
23
namespace
divide_and_conquer
{
29
namespace
karatsuba_algorithm
{
36
std::string
add_strings
(std::string first, std::string second) {
37
std::string result;
// to store the resulting sum bits
38
39
// make the string lengths equal
40
int64_t len1 = first.size();
41
int64_t len2 = second.size();
42
std::string zero =
"0"
;
43
if
(len1 < len2) {
44
for
(int64_t i = 0; i < len2 - len1; i++) {
45
zero += first;
46
first = zero;
47
zero =
"0"
;
// Prevents CI from failing
48
}
49
}
else
if
(len1 > len2) {
50
for
(int64_t i = 0; i < len1 - len2; i++) {
51
zero += second;
52
second = zero;
53
zero =
"0"
;
// Prevents CI from failing
54
}
55
}
56
57
int64_t length = std::max(len1, len2);
58
int64_t carry = 0;
59
for
(int64_t i = length - 1; i >= 0; i--) {
60
int64_t firstBit = first.at(i) -
'0'
;
61
int64_t secondBit = second.at(i) -
'0'
;
62
63
int64_t sum = (char(firstBit ^ secondBit ^ carry)) +
'0'
;
// sum of 3 bits
64
result.insert(result.begin(), sum);
65
66
carry = char((firstBit & secondBit) | (secondBit & carry) |
67
(firstBit & carry));
// sum of 3 bits
68
}
69
70
if
(carry) {
71
result.insert(result.begin(),
'1'
);
// adding 1 incase of overflow
72
}
73
return
result;
74
}
75
85
std::string
safe_substr
(
const
std::string &str, int64_t x1, int64_t x2, int64_t n) {
86
int64_t len = str.size();
87
88
if
(len >= n) {
89
return
str.substr(x1, x2);
90
}
91
92
int64_t y1 = x1 - (n - len);
// index in str of first char of substring of "whole" string
93
int64_t y2 = (x1 + x2 - 1) - (n - len);
// index in str of last char of substring of "whole" string
94
95
if
(y2 < 0) {
96
return
"0"
;
97
}
else
if
(y1 < 0) {
98
return
str.substr(0, y2 + 1);
99
}
else
{
100
return
str.substr(y1, x2);
101
}
102
}
103
111
int64_t
karatsuba_algorithm
(std::string str1, std::string str2) {
112
int64_t len1 = str1.size();
113
int64_t len2 = str2.size();
114
int64_t n = std::max(len1, len2);
115
116
if
(n == 0) {
117
return
0;
118
}
119
if
(n == 1) {
120
return
(str1[0] -
'0'
) * (str2[0] -
'0'
);
121
}
122
123
int64_t fh = n / 2;
// first half of string
124
int64_t sh = n - fh;
// second half of string
125
126
std::string Xl =
divide_and_conquer::karatsuba_algorithm::safe_substr
(str1, 0, fh, n);
// first half of first string
127
std::string Xr =
divide_and_conquer::karatsuba_algorithm::safe_substr
(str1, fh, sh, n);
// second half of first string
128
129
std::string Yl =
divide_and_conquer::karatsuba_algorithm::safe_substr
(str2, 0, fh, n);
// first half of second string
130
std::string Yr =
divide_and_conquer::karatsuba_algorithm::safe_substr
(str2, fh, sh, n);
// second half of second string
131
132
// calculating the three products of inputs of size n/2 recursively
133
int64_t product1 =
karatsuba_algorithm
(Xl, Yl);
134
int64_t product2 =
karatsuba_algorithm
(Xr, Yr);
135
int64_t product3 =
karatsuba_algorithm
(
136
divide_and_conquer::karatsuba_algorithm::add_strings
(Xl, Xr),
137
divide_and_conquer::karatsuba_algorithm::add_strings
(Yl, Yr));
138
139
return
product1 * (1 << (2 * sh)) +
140
(product3 - product1 - product2) * (1 << sh) +
141
product2;
// combining the three products to get the final result.
142
}
143
}
// namespace karatsuba_algorithm
144
}
// namespace divide_and_conquer
145
150
static
void
test
() {
151
// 1st test
152
std::string s11 =
"1"
;
// 1
153
std::string s12 =
"1010"
;
// 10
154
std::cout <<
"1st test... "
;
155
assert(
divide_and_conquer::karatsuba_algorithm::karatsuba_algorithm
(
156
s11, s12) == 10);
157
std::cout <<
"passed"
<< std::endl;
158
159
// 2nd test
160
std::string s21 =
"11"
;
// 3
161
std::string s22 =
"1010"
;
// 10
162
std::cout <<
"2nd test... "
;
163
assert(
divide_and_conquer::karatsuba_algorithm::karatsuba_algorithm
(
164
s21, s22) == 30);
165
std::cout <<
"passed"
<< std::endl;
166
167
// 3rd test
168
std::string s31 =
"110"
;
// 6
169
std::string s32 =
"1010"
;
// 10
170
std::cout <<
"3rd test... "
;
171
assert(
divide_and_conquer::karatsuba_algorithm::karatsuba_algorithm
(
172
s31, s32) == 60);
173
std::cout <<
"passed"
<< std::endl;
174
}
175
180
int
main
() {
181
test
();
// run self-test implementations
182
return
0;
183
}
test
void test()
Definition
caesar_cipher.cpp:100
main
int main()
Main function.
Definition
generate_parentheses.cpp:110
divide_and_conquer::karatsuba_algorithm::karatsuba_algorithm
int64_t karatsuba_algorithm(std::string str1, std::string str2)
The main function implements Karatsuba's algorithm for fast multiplication.
Definition
karatsuba_algorithm_for_fast_multiplication.cpp:111
divide_and_conquer::karatsuba_algorithm::safe_substr
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:85
divide_and_conquer::karatsuba_algorithm::add_strings
std::string add_strings(std::string first, std::string second)
Binary addition.
Definition
karatsuba_algorithm_for_fast_multiplication.cpp:36
divide_and_conquer
for IO operations
karatsuba_algorithm
Functions for the Karatsuba algorithm for fast multiplication implementation.
divide_and_conquer
karatsuba_algorithm_for_fast_multiplication.cpp
Generated by
1.18.0