Merge branch 'TheAlgorithms:master' into master

This commit is contained in:
Nitin Sharma 2021-08-12 12:02:02 +05:30 committed by GitHub
commit 8bc34eb8a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 553 additions and 4 deletions

View File

@ -11,9 +11,11 @@
* [Subarray Sum](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/subarray_sum.cpp)
* [Subset Sum](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/subset_sum.cpp)
* [Sudoku Solve](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/sudoku_solve.cpp)
* [Wildcard Matching](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/wildcard_matching.cpp)
## Bit Manipulation
* [Count Of Set Bits](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/bit_manipulation/count_of_set_bits.cpp)
* [Count Of Trailing Ciphers In Factorial N](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/bit_manipulation/count_of_trailing_ciphers_in_factorial_n.cpp)
* [Hamming Distance](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/bit_manipulation/hamming_distance.cpp)
## Ciphers
@ -64,6 +66,9 @@
* [Trie Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/trie_tree.cpp)
* [Trie Using Hashmap](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/trie_using_hashmap.cpp)
## Divide And Conquer
* [Karatsuba Algorithm For Fast Multiplication](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/divide_and_conquer/karatsuba_algorithm_for_fast_multiplication.cpp)
## Dynamic Programming
* [0 1 Knapsack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/0_1_knapsack.cpp)
* [Abbreviation](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/abbreviation.cpp)
@ -180,6 +185,7 @@
* [Modular Division](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/modular_division.cpp)
* [Modular Exponentiation](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/modular_exponentiation.cpp)
* [Modular Inverse Fermat Little Theorem](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/modular_inverse_fermat_little_theorem.cpp)
* [N Bonacci](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/n_bonacci.cpp)
* [N Choose R](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/n_choose_r.cpp)
* [Ncr Modulo P](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/ncr_modulo_p.cpp)
* [Number Of Positive Divisors](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/number_of_positive_divisors.cpp)

View File

@ -0,0 +1,155 @@
/**
* @file
* @brief Implementation of the [Wildcard
* Matching](https://www.geeksforgeeks.org/wildcard-pattern-matching/) problem.
* @details
* Given a matching string and a pattern, implement wildcard pattern
* matching with support for `?` and `*`. `?` matches any single character.
* `*` matches any sequence of characters (including the empty sequence).
* The matching should cover the entire matching string (not partial). The task
* is to determine if the pattern matches with the matching string
* @author [Swastika Gupta](https://github.com/Swastyy)
*/
#include <cassert> /// for assert
#include <iostream> /// for IO operations
#include <vector> /// for std::vector
/**
* @namespace backtracking
* @brief Backtracking algorithms
*/
namespace backtracking {
/**
* @namespace wildcard_matching
* @brief Functions for the [Wildcard
* Matching](https://www.geeksforgeeks.org/wildcard-pattern-matching/) problem.
*/
namespace wildcard_matching {
/**
* @brief The main function implements if pattern can be matched with given
* string
* @param s is the given matching string
* @param p is the given pattern
* @param pos1 is the starting index
* @param pos2 is the last index
* @returns 1 if pattern matches with matching string otherwise 0
*/
std::vector<std::vector<int64_t>> dpTable(1000, std::vector<int64_t>(1000, -1));
bool wildcard_matching(std::string s, std::string p, uint32_t pos1,
uint32_t pos2) {
uint32_t n = s.length();
uint32_t m = p.length();
// matching is successfull if both strings are done
if (pos1 == n && pos2 == m) {
return true;
}
// matching is unsuccessfull if pattern is not finished but matching string
// is
if (pos1 != n && pos2 == m) {
return false;
}
// all the remaining characters of patterns must be * inorder to match with
// finished string
if (pos1 == n && pos2 != m) {
while (pos2 < m && p[pos2] == '*') {
pos2++;
}
return pos2 == m;
}
// if already calculted for these positions
if (dpTable[pos1][pos2] != -1) {
return dpTable[pos1][pos2];
}
// if the characters are same just go ahead in both the string
if (s[pos1] == p[pos2]) {
return dpTable[pos1][pos2] =
wildcard_matching(s, p, pos1 + 1, pos2 + 1);
}
else {
// can only single character
if (p[pos2] == '?') {
return dpTable[pos1][pos2] =
wildcard_matching(s, p, pos1 + 1, pos2 + 1);
}
// have choice either to match one or more charcters
else if (p[pos2] == '*') {
return dpTable[pos1][pos2] =
wildcard_matching(s, p, pos1, pos2 + 1) ||
wildcard_matching(s, p, pos1 + 1, pos2);
}
// not possible to match
else {
return dpTable[pos1][pos2] = 0;
}
}
}
} // namespace wildcard_matching
} // namespace backtracking
/**
* @brief Self-test implementations
* @returns void
*/
static void test() {
// 1st test
std::cout << "1st test ";
std::string matching1 = "baaabab";
std::string pattern1 = "*****ba*****ab";
assert(backtracking::wildcard_matching::wildcard_matching(matching1,
pattern1, 0, 0) ==
1); // here the pattern matches with given string
std::cout << "passed" << std::endl;
// 2nd test
std::cout << "2nd test ";
std::string matching2 = "baaabab";
std::string pattern2 = "ba*****ab";
assert(backtracking::wildcard_matching::wildcard_matching(matching2,
pattern2, 0, 0) ==
1); // here the pattern matches with given string
std::cout << "passed" << std::endl;
// 3rd test
std::cout << "3rd test ";
std::string matching3 = "baaabab";
std::string pattern3 = "ba*ab";
assert(backtracking::wildcard_matching::wildcard_matching(matching3,
pattern3, 0, 0) ==
1); // here the pattern matches with given string
std::cout << "passed" << std::endl;
// 4th test
std::cout << "4th test ";
std::string matching4 = "baaabab";
std::string pattern4 = "a*ab";
assert(backtracking::wildcard_matching::wildcard_matching(matching4,
pattern4, 0, 0) ==
1); // here the pattern matches with given string
std::cout << "passed" << std::endl;
// 5th test
std::cout << "5th test ";
std::string matching5 = "baaabab";
std::string pattern5 = "aa?ab";
assert(backtracking::wildcard_matching::wildcard_matching(matching5,
pattern5, 0, 0) ==
1); // here the pattern matches with given string
std::cout << "passed" << std::endl;
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main() {
test(); // run self-test implementations
return 0;
}

View File

@ -0,0 +1,98 @@
/**
* @file
* @brief [Count the number of
* ciphers](https://www.tutorialspoint.com/count-trailing-zeros-in-factorial-of-a-number-in-cplusplus) in `n!` implementation
* @details
* Given an integer number as input. The goal is to find the number of trailing
zeroes in the factorial calculated for
* that number. A factorial of a number N is a product of all numbers in the
range [1, N].
* We know that we get a trailing zero only if the number is multiple of 10 or
has a factor pair (2,5). In all factorials of
* any number greater than 5, we have many 2s more than 5s in the prime
factorization of that number. Dividing a
* number by powers of 5 will give us the count of 5s in its factors. So, the
number of 5s will tell us the number of trailing zeroes.
* @author [Swastika Gupta](https://github.com/Swastyy)
*/
#include <cassert> /// for assert
#include <iostream> /// for IO operations
/**
* @namespace bit_manipulation
* @brief Bit manipulation algorithms
*/
namespace bit_manipulation {
/**
* @namespace count_of_trailing_ciphers_in_factorial_n
* @brief Functions for the [Count the number of
* ciphers](https://www.tutorialspoint.com/count-trailing-zeros-in-factorial-of-a-number-in-cplusplus)
* in `n!` implementation
*/
namespace count_of_trailing_ciphers_in_factorial_n {
/**
* @brief Function to count the number of the trailing ciphers
* @param n number for which `n!` ciphers are returned
* @return count, Number of ciphers in `n!`.
*/
uint64_t numberOfCiphersInFactorialN(uint64_t n) {
// count is to store the number of 5's in factorial(n)
uint64_t count = 0;
// Keep dividing n by powers of
// 5 and update count
for (uint64_t i = 5; n / i >= 1; i *= 5) {
count += static_cast<uint64_t>(n) / i;
}
return count;
}
} // namespace count_of_trailing_ciphers_in_factorial_n
} // namespace bit_manipulation
/**
* @brief Self-test implementations
* @returns void
*/
static void test() {
// 1st test
std::cout << "1st test ";
assert(bit_manipulation::count_of_trailing_ciphers_in_factorial_n::
numberOfCiphersInFactorialN(395) == 97);
std::cout << "passed" << std::endl;
// 2nd test
std::cout << "2nd test ";
assert(bit_manipulation::count_of_trailing_ciphers_in_factorial_n::
numberOfCiphersInFactorialN(977) == 242);
std::cout << "passed" << std::endl;
// 3rd test
std::cout << "3rd test ";
assert(bit_manipulation::count_of_trailing_ciphers_in_factorial_n::
numberOfCiphersInFactorialN(871) == 215);
std::cout << "passed" << std::endl;
// 4th test
std::cout << "4th test ";
assert(bit_manipulation::count_of_trailing_ciphers_in_factorial_n::
numberOfCiphersInFactorialN(239) == 57);
std::cout << "passed" << std::endl;
// 5th test
std::cout << "5th test ";
assert(bit_manipulation::count_of_trailing_ciphers_in_factorial_n::
numberOfCiphersInFactorialN(0) == 0);
std::cout << "passed" << std::endl;
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main() {
test(); // run self-test implementations
return 0;
}

View File

@ -0,0 +1,167 @@
/**
* @file
* @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.
* @author [Swastika Gupta](https://github.com/Swastyy)
*/
#include <cassert> /// for assert
#include <cstring> /// for string
#include <iostream> /// for IO operations
#include <vector> /// for std::vector
/**
* @namespace divide_and_conquer
* @brief Divide and Conquer algorithms
*/
namespace divide_and_conquer {
/**
* @namespace 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
* @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 result; // To store the resulting sum bits
int64_t len1 = first.size();
int64_t len2 = second.size();
int64_t length = std::max(len1, len2);
std::string zero = "0";
if (len1 < len2) // make the string lengths equal
{
for (int64_t i = 0; i < len2 - len1; i++) {
zero += first;
first = zero;
}
} else if (len1 > len2) {
zero = "0";
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 firstBit = first.at(i) - '0';
int64_t secondBit = second.at(i) - '0';
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
}
if (carry) {
result = '1' + result; // adding 1 incase of overflow
}
return result;
}
/**
* @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
*/
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);
std::string zero = "0";
if (len1 < len2) {
for (int64_t i = 0; i < len2 - len1; i++) {
zero += str1;
str1 = zero;
}
} else if (len1 > len2) {
zero = "0";
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
// 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 << sh) +
product2; // combining the three products to get the final result.
}
} // namespace karatsuba_algorithm
} // namespace divide_and_conquer
/**
* @brief Self-test implementations
* @returns void
*/
static void test() {
// 1st test
std::string s11 = "1";
std::string s12 = "1010";
std::cout << "1st test... ";
assert(divide_and_conquer::karatsuba_algorithm::karatsuba_algorithm(
s11, s12) == 10); // here the multiplication is 10
std::cout << "passed" << std::endl;
// 2nd test
std::string s21 = "11";
std::string s22 = "1010";
std::cout << "2nd test... ";
assert(divide_and_conquer::karatsuba_algorithm::karatsuba_algorithm(
s21, s22) == 30); // here the multiplication is 30
std::cout << "passed" << std::endl;
// 3rd test
std::string s31 = "110";
std::string s32 = "1010";
std::cout << "3rd test... ";
assert(divide_and_conquer::karatsuba_algorithm::karatsuba_algorithm(
s31, s32) == 60); // here the multiplication is 60
std::cout << "passed" << std::endl;
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main() {
test(); // run self-test implementations
return 0;
}

View File

@ -22,11 +22,11 @@ template <typename T>
bool is_prime(T num) {
bool result = true;
if (num <= 1) {
return 0;
return false;
} else if (num == 2) {
return 1;
return true;
} else if ((num & 1) == 0) {
return 0;
return false;
}
if (num >= 3) {
for (T i = 3; (i * i) <= (num); i = (i + 2)) {
@ -47,7 +47,7 @@ int main() {
assert(is_prime(50) == false);
assert(is_prime(115249) == true);
int num;
int num = 0;
std::cout << "Enter the number to check if it is prime or not" << std::endl;
std::cin >> num;
bool result = is_prime(num);

123
math/n_bonacci.cpp Normal file
View File

@ -0,0 +1,123 @@
/**
* @file
* @brief Implementation of the
* [N-bonacci](http://oeis.org/wiki/N-bonacci_numbers) series
*
* @details
* In general, in N-bonacci sequence,
* we generate sum of preceding N numbers from the next term.
*
* For example, a 3-bonacci sequence is the following:
* 0, 0, 1, 1, 2, 4, 7, 13, 24, 44, 81
* In this code we take N and M as input where M is the number of terms
* to be printed of the N-bonacci series
*
* @author [Swastika Gupta](https://github.com/Swastyy)
*/
#include <algorithm> /// for std::is_equal, std::swap
#include <cassert> /// for assert
#include <iostream> /// for IO operations
#include <vector> /// for std::vector
/**
* @namespace math
* @brief Mathematical algorithms
*/
namespace math {
/**
* @namespace n_bonacci
* @brief Functions for the [N-bonacci](http://oeis.org/wiki/N-bonacci_numbers)
* implementation
*/
namespace n_bonacci {
/**
* @brief Finds the N-Bonacci series for the `n` parameter value and `m`
* parameter terms
* @param n is in the N-Bonacci series
* @param m is the number of terms in the N-Bonacci sequence
* @returns the n-bonacci sequence as vector array
*/
std::vector<uint64_t> N_bonacci(const uint64_t &n, const uint64_t &m) {
std::vector<uint64_t> a(m, 0); // we create an empty array of size m
a[n - 1] = 1; /// we initialise the (n-1)th term as 1 which is the sum of
/// preceding N zeros
a[n] = 1; /// similarily the sum of preceding N zeros and the (N+1)th 1 is
/// also 1
for (uint64_t i = n + 1; i < m; i++) {
// this is an optimized solution that works in O(M) time and takes O(M)
// extra space here we use the concept of the sliding window the current
// term can be computed using the given formula
a[i] = 2 * a[i - 1] - a[i - 1 - n];
}
return a;
}
} // namespace n_bonacci
} // namespace math
/**
* @brief Self-test implementations
* @returns void
*/
static void test() {
// n = 1 m = 1 return [1, 1]
std::cout << "1st test";
std::vector<uint64_t> arr1 = math::n_bonacci::N_bonacci(
1, 1); // first input is the param n and second one is the param m for
// N-bonacci func
std::vector<uint64_t> output_array1 = {
1, 1}; // It is the expected output series of length m
assert(std::equal(std::begin(arr1), std::end(arr1),
std::begin(output_array1)));
std::cout << "passed" << std::endl;
// n = 5 m = 15 return [0, 0, 0, 0, 1, 1, 2, 4, 8, 16, 31, 61, 120, 236,
// 464]
std::cout << "2nd test";
std::vector<uint64_t> arr2 = math::n_bonacci::N_bonacci(
5, 15); // first input is the param n and second one is the param m for
// N-bonacci func
std::vector<uint64_t> output_array2 = {
0, 0, 0, 0, 1, 1, 2, 4,
8, 16, 31, 61, 120, 236, 464}; // It is the expected output series of
// length m
assert(std::equal(std::begin(arr2), std::end(arr2),
std::begin(output_array2)));
std::cout << "passed" << std::endl;
// n = 6 m = 17 return [0, 0, 0, 0, 0, 1, 1, 2, 4, 8, 16, 32, 63, 125, 248,
// 492, 976]
std::cout << "3rd test";
std::vector<uint64_t> arr3 = math::n_bonacci::N_bonacci(
6, 17); // first input is the param n and second one is the param m for
// N-bonacci func
std::vector<uint64_t> output_array3 = {
0, 0, 0, 0, 0, 1, 1, 2, 4,
8, 16, 32, 63, 125, 248, 492, 976}; // It is the expected output series
// of length m
assert(std::equal(std::begin(arr3), std::end(arr3),
std::begin(output_array3)));
std::cout << "passed" << std::endl;
// n = 56 m = 15 return [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
std::cout << "4th test";
std::vector<uint64_t> arr4 = math::n_bonacci::N_bonacci(
56, 15); // first input is the param n and second one is the param m
// for N-bonacci func
std::vector<uint64_t> output_array4 = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0}; // It is the expected output series of length m
assert(std::equal(std::begin(arr4), std::end(arr4),
std::begin(output_array4)));
std::cout << "passed" << std::endl;
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main() {
test(); // run self-test implementations
return 0;
}