mirror of
https://github.com/TheAlgorithms/C-Plus-Plus.git
synced 2026-02-03 02:25:57 +08:00
Merge branch 'master' into aminos
This commit is contained in:
@@ -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)
|
||||
@@ -181,6 +186,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)
|
||||
@@ -237,6 +243,7 @@
|
||||
* [Fast Integer Input](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/fast_integer_input.cpp)
|
||||
* [Happy Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/happy_number.cpp)
|
||||
* [Iterative Tree Traversals](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/iterative_tree_traversals.cpp)
|
||||
* [Lru Cache](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/lru_cache.cpp)
|
||||
* [Matrix Exponentiation](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/matrix_exponentiation.cpp)
|
||||
* [Palindrome Of Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/palindrome_of_number.cpp)
|
||||
* [Paranthesis Matching](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/paranthesis_matching.cpp)
|
||||
@@ -292,6 +299,7 @@
|
||||
* [Counting Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/counting_sort.cpp)
|
||||
* [Counting Sort String](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/counting_sort_string.cpp)
|
||||
* [Cycle Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/cycle_sort.cpp)
|
||||
* [Dnf Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/dnf_sort.cpp)
|
||||
* [Gnome Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/gnome_sort.cpp)
|
||||
* [Heap Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/heap_sort.cpp)
|
||||
* [Insertion Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/insertion_sort.cpp)
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
|
||||
## Overview
|
||||
|
||||
The repository is a collection of open-source implementation of a variety of algorithms implemented in C++ and licensed under [MIT License](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/LICENSE). The algorithms span a variety of topics from computer science, mathematics and statistics, data science, machine learning, engineering, etc.. The implementations and the associated documentation are meant to provide a learning resource for educators and students. Hence, one may find more than one implementation for the same objective but using a different algorithm strategies and optimizations.
|
||||
The repository is a collection of open-source implementation of a variety of algorithms implemented in C++ and licensed under [MIT License](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/LICENSE). These algorithms span a variety of topics from computer science, mathematics and statistics, data science, machine learning, engineering, etc.. The implementations and the associated documentation are meant to provide a learning resource for educators and students. Hence, one may find more than one implementation for the same objective but using a different algorithm strategies and optimizations.
|
||||
|
||||
## Features
|
||||
|
||||
* The repository provides implementations of various algorithms in one of the most fundamental general purpose languages - [C++](https://en.wikipedia.org/wiki/C%2B%2B).
|
||||
* Well documented source code with detailed explanations provide a valuable resource for educators and students alike.
|
||||
* Each source code is atomic using [STL classes](https://en.wikipedia.org/wiki/Standard_Template_Library) and _no external libraries_ are required for their compilation and execution. Thus the fundamentals of the algorithms can be studied in much depth.
|
||||
* Each source code is atomic using [STL classes](https://en.wikipedia.org/wiki/Standard_Template_Library) and _no external libraries_ are required for their compilation and execution. Thus, the fundamentals of the algorithms can be studied in much depth.
|
||||
* Source codes are [compiled and tested](https://github.com/TheAlgorithms/C-Plus-Plus/actions?query=workflow%3A%22Awesome+CI+Workflow%22) for every commit on the latest versions of three major operating systems viz., Windows, MacOS and Ubuntu (Linux) using MSVC 16 2019, AppleClang 11.0 and GNU 7.5.0 respectively.
|
||||
* Strict adherence to [C++11](https://en.wikipedia.org/wiki/C%2B%2B11) standard ensures portability of code to embedded systems as well like ESP32, ARM Cortex, etc. with little to no changes.
|
||||
* Self-checks within programs ensure correct implementations with confidence.
|
||||
|
||||
155
backtracking/wildcard_matching.cpp
Normal file
155
backtracking/wildcard_matching.cpp
Normal 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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -24,7 +24,7 @@ class hash_chain {
|
||||
};
|
||||
|
||||
std::vector<std::shared_ptr<Node>> head; ///< array of nodes
|
||||
int _mod; ///< modulus of the class
|
||||
int _mod; ///< modulus of the class
|
||||
|
||||
public:
|
||||
/**
|
||||
@@ -67,10 +67,10 @@ class hash_chain {
|
||||
if (!head[i]) {
|
||||
std::cout << "Key " << i << " is empty" << std::endl;
|
||||
} else {
|
||||
std::cout << "Key " << i << " has values = ";
|
||||
std::cout << "Key " << i << " has values = " << std::endl;
|
||||
temp = head[i];
|
||||
while (temp->next) {
|
||||
std::cout << temp->data << " ";
|
||||
std::cout << temp->data << " " << std::endl;
|
||||
temp = temp->next;
|
||||
}
|
||||
std::cout << temp->data;
|
||||
@@ -102,7 +102,7 @@ class hash_chain {
|
||||
std::shared_ptr<Node> temp = head[h];
|
||||
if (!head[h]) {
|
||||
// index does not exist!
|
||||
std::cout << "Element not found";
|
||||
std::cout << "Element not found" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -110,19 +110,19 @@ class hash_chain {
|
||||
while (temp->data != x && temp->next) temp = temp->next;
|
||||
|
||||
if (temp->next) {
|
||||
std::cout << "Element found";
|
||||
std::cout << "Element found" << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
// implicit else condition
|
||||
// i.e., temp->next == nullptr
|
||||
if (temp->data == x) {
|
||||
std::cout << "Element found";
|
||||
std::cout << "Element found" << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
// further implicit else condition
|
||||
std::cout << "Element not found";
|
||||
std::cout << "Element not found" << std::endl;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -132,7 +132,7 @@ class hash_chain {
|
||||
*/
|
||||
int main() {
|
||||
int c = 0, x = 0, mod = 0, h = 0;
|
||||
std::cout << "Enter the size of Hash Table. = ";
|
||||
std::cout << "Enter the size of Hash Table. = " << std::endl;
|
||||
std::cin >> mod;
|
||||
|
||||
hash_chain mychain(mod);
|
||||
@@ -149,22 +149,23 @@ int main() {
|
||||
std::cin >> c;
|
||||
switch (c) {
|
||||
case 1:
|
||||
std::cout << "Enter element to add = ";
|
||||
std::cout << "Enter element to add = " << std::endl;
|
||||
std::cin >> x;
|
||||
h = mychain.hash(x);
|
||||
h = std::abs(h);
|
||||
mychain.add(x, h);
|
||||
break;
|
||||
case 2:
|
||||
std::cout << "Enter element to search = ";
|
||||
std::cout << "Enter element to search = " << std::endl;
|
||||
std::cin >> x;
|
||||
h = mychain.hash(x);
|
||||
mychain.find(x, h);
|
||||
break;
|
||||
case 3:
|
||||
std::cout << "Enter element to generate hash = ";
|
||||
std::cout << "Enter element to generate hash = " << std::endl;
|
||||
std::cin >> x;
|
||||
std::cout << "Hash of " << x << " is = " << mychain.hash(x);
|
||||
std::cout << "Hash of " << x << " is = " << mychain.hash(x)
|
||||
<< std::endl;
|
||||
break;
|
||||
case 4:
|
||||
mychain.display();
|
||||
|
||||
123
math/n_bonacci.cpp
Normal file
123
math/n_bonacci.cpp
Normal 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;
|
||||
}
|
||||
268
others/lru_cache.cpp
Normal file
268
others/lru_cache.cpp
Normal file
@@ -0,0 +1,268 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief An implementation of
|
||||
* [LRU
|
||||
* Cache](https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)).
|
||||
* Lru is a part of cache algorithms (also frequently called cache replacement
|
||||
* algorithms or cache replacement policies).
|
||||
*
|
||||
* ### Logic
|
||||
* * Discards the least recently used items first.
|
||||
* * This algorithm requires keeping track of what was used when, which is
|
||||
* expensive if one wants to make sure the algorithm always discards the least
|
||||
* recently used item.
|
||||
* * General implementations of this technique require keeping "age bits"
|
||||
* for cache-lines and track the "Least Recently Used" cache-line based on
|
||||
* age-bits.
|
||||
* * In such an implementation, every time a cache-line is used, the age of
|
||||
* all other cache-lines changes
|
||||
*
|
||||
* ### Algorithm explanation
|
||||
* For a cache of page frame x:
|
||||
* * Check if the page is present in cache.
|
||||
* * If not present, then check is the cache is full or not:
|
||||
* * If the cache is full, REMOVE the last element from the cache.
|
||||
* * If the element is present in cache, then shift that element to
|
||||
* first position in cache from its original position.
|
||||
* * This way you can keep the least recently used elements in the
|
||||
* last and most recently used in front of the cache.
|
||||
*
|
||||
* Every time a requested page is not found in cache, that is a miss or page
|
||||
* fault, and if the page is present in cache, then its a hit.
|
||||
*
|
||||
* ## Data Structure used
|
||||
* * In the algorithm below we used two different data structure, one is linked
|
||||
* list and other one is a hash map
|
||||
* * The linked list is used to contain the pages and the hash map contains the
|
||||
* pages and their address.
|
||||
* * Every time a new page is requested, we first check in the hash map if the
|
||||
* page is present or not.
|
||||
* * If not present, and the cache is full, we simply delete the last entry in
|
||||
* the cache.
|
||||
* * If present, we shift that page from its current location to beginning of
|
||||
* the cache and update the address in hash map for that page.
|
||||
*
|
||||
* @author [Nitin Sharma](https://github.com/foo290)
|
||||
* */
|
||||
|
||||
#include <cassert> /// for assert
|
||||
#include <iostream> /// for IO Operations
|
||||
#include <list> /// for std::list
|
||||
#include <unordered_map> /// for std::unordered_map
|
||||
|
||||
/**
|
||||
* @namespace others
|
||||
* @brief Other algorithms
|
||||
*/
|
||||
namespace others {
|
||||
/**
|
||||
* @namespace lru_cache
|
||||
* @brief Implementation of the [LRU caching
|
||||
* algorithm](https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU))
|
||||
*/
|
||||
namespace lru_cache {
|
||||
/**
|
||||
* @brief LRU cache class
|
||||
*/
|
||||
class LRUCache {
|
||||
uint64_t pageFrame; ///< Page frame, or total size of the cache.
|
||||
std::list<uint64_t> cache; ///< Cache linked list (using the STL)
|
||||
std::unordered_map<uint64_t, std::list<uint64_t>::iterator>
|
||||
pageMap; ///< Hash map containing pages and their addresses
|
||||
|
||||
uint64_t hits =
|
||||
0; ///< Total number of hits, or total number of times a page
|
||||
///< was found in cache.
|
||||
uint64_t pageFault = 0; ///< Total number of miss/page fault, or total
|
||||
///< number of times a page was not found in cache
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor, Initialize thee LRU class with page frame.
|
||||
* @param pf Page frame or total size of cache.
|
||||
* */
|
||||
explicit LRUCache(uint64_t pf) { pageFrame = pf; }
|
||||
|
||||
/**
|
||||
* @brief Refer to a page, or request a page from memory.
|
||||
* @param page The page that you are referring to.
|
||||
* @returns void
|
||||
* */
|
||||
void refer(uint64_t page) {
|
||||
// If the page requested not in cache.
|
||||
if (pageMap.find(page) == pageMap.end()) {
|
||||
pageFault++; ///< Increase the page fault by one.
|
||||
|
||||
// Check if the cache is full
|
||||
if (cache.size() == pageFrame) {
|
||||
// delete the last page from cache
|
||||
uint64_t lastPage = cache.back();
|
||||
cache.pop_back();
|
||||
pageMap.erase(lastPage);
|
||||
}
|
||||
}
|
||||
// The requested page is in the cache
|
||||
else {
|
||||
hits++;
|
||||
// present in cache, erase from current position to bring in front
|
||||
cache.erase(pageMap[page]);
|
||||
}
|
||||
// Push it in the front of the cache and update the page reference in
|
||||
// page map.
|
||||
cache.push_front(page);
|
||||
pageMap[page] = cache.begin();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief A function to display the current cache
|
||||
* @returns Void
|
||||
* */
|
||||
void display() {
|
||||
for (uint64_t &it : cache) {
|
||||
std::cout << it << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
/**
|
||||
* @brief A function to get page hits
|
||||
* @returns int
|
||||
* */
|
||||
uint64_t getHits() const { return hits; }
|
||||
/**
|
||||
* @brief A function to get page fault
|
||||
* @returns int
|
||||
* */
|
||||
uint64_t getPageFault() const { return pageFault; }
|
||||
};
|
||||
|
||||
} // namespace lru_cache
|
||||
} // namespace others
|
||||
|
||||
namespace lru_tests {
|
||||
/**
|
||||
* @brief A function to print given message on console.
|
||||
* @tparam T Type of the given message.
|
||||
* @returns void
|
||||
* */
|
||||
template <typename T>
|
||||
void log(T msg) {
|
||||
// It's just to avoid writing cout and endl
|
||||
std::cout << "[TESTS] : ---> " << msg << std::endl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief A simple test case
|
||||
* The assert statement will check expected hist and miss to resultant hits and
|
||||
* miss
|
||||
* @returns void
|
||||
* */
|
||||
static void test_1() {
|
||||
uint64_t expected_hits = 2;
|
||||
uint64_t expected_pageFault = 4;
|
||||
|
||||
log("Running Test-1...");
|
||||
|
||||
others::lru_cache::LRUCache cache(4);
|
||||
cache.refer(1);
|
||||
cache.refer(2);
|
||||
cache.refer(5);
|
||||
cache.refer(1);
|
||||
cache.refer(4);
|
||||
cache.refer(5);
|
||||
|
||||
log("Checking assert statement...");
|
||||
assert(cache.getHits() == expected_hits &&
|
||||
cache.getPageFault() == expected_pageFault);
|
||||
log("Assert successful!");
|
||||
log("Test-1 complete!");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief A test case contains hits more than cache size
|
||||
* The assert statement will check expected hist and miss to resultant hits and
|
||||
* miss
|
||||
* @returns void
|
||||
* */
|
||||
static void test_2() {
|
||||
uint64_t expected_hits = 4;
|
||||
uint64_t expected_pageFault = 2;
|
||||
|
||||
log("Running Test-2...");
|
||||
|
||||
others::lru_cache::LRUCache cache(4);
|
||||
cache.refer(1);
|
||||
cache.refer(1);
|
||||
cache.refer(1);
|
||||
cache.refer(1);
|
||||
cache.refer(1);
|
||||
cache.refer(5);
|
||||
|
||||
log("Checking assert statement...");
|
||||
assert(cache.getHits() == expected_hits &&
|
||||
cache.getPageFault() == expected_pageFault);
|
||||
log("Assert successful!");
|
||||
log("Test-2 complete!");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief A simple test case
|
||||
* The assert statement will check expected hist and miss to resultant hits and
|
||||
* miss
|
||||
* @returns void
|
||||
* */
|
||||
static void test_3() {
|
||||
uint64_t expected_hits = 1;
|
||||
uint64_t expected_pageFault = 5;
|
||||
|
||||
log("Running Test-3...");
|
||||
|
||||
others::lru_cache::LRUCache cache(4);
|
||||
cache.refer(1);
|
||||
cache.refer(2);
|
||||
cache.refer(3);
|
||||
cache.refer(4);
|
||||
cache.refer(5);
|
||||
cache.refer(5);
|
||||
|
||||
log("Checking assert statement...");
|
||||
assert(cache.getHits() == expected_hits &&
|
||||
cache.getPageFault() == expected_pageFault);
|
||||
log("Assert successful!");
|
||||
log("Test-3 complete!");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief A function to invoke all test cases
|
||||
* @returns void
|
||||
* */
|
||||
static void run_tests() {
|
||||
test_1();
|
||||
test_2();
|
||||
test_3();
|
||||
log("");
|
||||
log("TESTS COMPLETED!");
|
||||
}
|
||||
} // namespace lru_tests
|
||||
|
||||
/**
|
||||
* @brief Main function
|
||||
* @returns 0 on exit
|
||||
*/
|
||||
int main() {
|
||||
lru_tests::run_tests();
|
||||
|
||||
// Usage
|
||||
others::lru_cache::LRUCache cache(4);
|
||||
cache.refer(1);
|
||||
cache.refer(2);
|
||||
cache.refer(3);
|
||||
cache.refer(4);
|
||||
cache.refer(5);
|
||||
cache.refer(5);
|
||||
|
||||
cache.display();
|
||||
|
||||
std::cout << "Hits: " << cache.getHits()
|
||||
<< " Miss: " << cache.getPageFault() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
109
sorting/dnf_sort.cpp
Normal file
109
sorting/dnf_sort.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Implementation of the [DNF
|
||||
* sort](https://www.geeksforgeeks.org/sort-an-array-of-0s-1s-and-2s/) implementation
|
||||
* @details
|
||||
* C++ program to sort an array with 0, 1 and 2 in a single pass(DNF sort).
|
||||
* Since one traversal of the array is there hence it works in O(n) time
|
||||
* complexity.
|
||||
* @author [Sujal Gupta](https://github.com/heysujal)
|
||||
*/
|
||||
|
||||
#include <algorithm> /// for std::is_sorted
|
||||
#include <cassert> /// for assert
|
||||
#include <iostream> /// for std::swap and io operations
|
||||
#include <vector> /// for std::vector
|
||||
|
||||
/**
|
||||
* @namespace sorting
|
||||
* @breif Sorting algorithms
|
||||
*/
|
||||
namespace sorting {
|
||||
/**
|
||||
* @namespace dnf_sort
|
||||
* @brief Functions for the [DNF
|
||||
* sort](https://en.wikipedia.org/wiki/Dutch_national_flag_problem) implementation
|
||||
*/
|
||||
namespace dnf_sort {
|
||||
/**
|
||||
* @brief The main function implements DNF sort
|
||||
* @tparam T type of array
|
||||
* @param a array to be sorted,
|
||||
* @param arr_size size of array
|
||||
* @returns void
|
||||
*/
|
||||
template <typename T>
|
||||
std::vector<T> dnfSort(const std::vector<T> &in_arr) {
|
||||
std::vector<T> arr(in_arr);
|
||||
uint64_t lo = 0;
|
||||
uint64_t hi = arr.size() - 1;
|
||||
uint64_t mid = 0;
|
||||
|
||||
// Iterate till all the elements
|
||||
// are sorted
|
||||
while (mid <= hi) {
|
||||
switch (arr[mid]) {
|
||||
// If the element is 0
|
||||
case 0:
|
||||
std::swap(arr[lo++], arr[mid++]);
|
||||
break;
|
||||
|
||||
// If the element is 1 .
|
||||
case 1:
|
||||
mid++;
|
||||
break;
|
||||
|
||||
// If the element is 2
|
||||
case 2:
|
||||
std::swap(arr[mid], arr[hi--]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
} // namespace dnf_sort
|
||||
} // namespace sorting
|
||||
|
||||
/**
|
||||
* @brief Self-test implementations
|
||||
* @returns void
|
||||
*/
|
||||
static void test() {
|
||||
// 1st test
|
||||
// [1, 0, 2, 1] return [0, 1, 1, 2]
|
||||
std::vector<uint64_t> array1 = {0, 1, 1, 2};
|
||||
std::cout << "Test 1... ";
|
||||
std::vector<uint64_t> arr1 = sorting::dnf_sort::dnfSort(array1);
|
||||
assert(std::is_sorted(std::begin(arr1), std::end(arr1)));
|
||||
std::cout << "passed" << std::endl;
|
||||
// 2nd test
|
||||
// [1, 0, 0, 1, 1, 0, 2, 1] return [0, 0, 0, 1, 1, 1, 1, 2]
|
||||
std::vector<uint64_t> array2 = {1, 0, 0, 1, 1, 0, 2, 1};
|
||||
std::cout << "Test 2... ";
|
||||
std::vector<uint64_t> arr2 = sorting::dnf_sort::dnfSort(array2);
|
||||
assert(std::is_sorted(std::begin(arr2), std::end(arr2)));
|
||||
std::cout << "passed" << std::endl;
|
||||
// 3rd test
|
||||
// [1, 1, 0, 0, 1, 2, 2, 0, 2, 1] return [0, 0, 0, 1, 1, 1, 1, 2, 2, 2]
|
||||
std::vector<uint64_t> array3 = {1, 1, 0, 0, 1, 2, 2, 0, 2, 1};
|
||||
std::cout << "Test 3... ";
|
||||
std::vector<uint64_t> arr3 = sorting::dnf_sort::dnfSort(array3);
|
||||
assert(std::is_sorted(std::begin(arr3), std::end(arr3)));
|
||||
std::cout << "passed" << std::endl;
|
||||
// 4th test
|
||||
// [2, 2, 2, 0, 0, 1, 1] return [0, 0, 1, 1, 2, 2, 2]
|
||||
std::vector<uint64_t> array4 = {2, 2, 2, 0, 0, 1, 1};
|
||||
std::cout << "Test 4... ";
|
||||
std::vector<uint64_t> arr4 = sorting::dnf_sort::dnfSort(array4);
|
||||
assert(std::is_sorted(std::begin(arr4), std::end(arr4)));
|
||||
std::cout << "passed" << std::endl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Main function
|
||||
* @returns 0 on exit
|
||||
*/
|
||||
int main() {
|
||||
test(); // execute the test
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user