mirror of
https://github.com/TheAlgorithms/C-Plus-Plus.git
synced 2026-04-01 09:43:06 +08:00
1
.gitignore
vendored
1
.gitignore
vendored
@@ -30,5 +30,6 @@
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
a.out
|
||||
*.out
|
||||
*.app
|
||||
|
||||
8
.vscode/settings.json
vendored
8
.vscode/settings.json
vendored
@@ -63,5 +63,9 @@
|
||||
"utility": "cpp",
|
||||
"valarray": "cpp",
|
||||
"algorithm": "cpp"
|
||||
}
|
||||
}
|
||||
},
|
||||
"C_Cpp.clang_format_style": "{BasedOnStyle: Google, IndentWidth: 4, ColumnLimit: 80, UseTab: Never}",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnType": true,
|
||||
"editor.formatOnPaste": true
|
||||
}
|
||||
|
||||
@@ -12,8 +12,11 @@ We are very happy that you consider implementing algorithms and data structures
|
||||
- You submitted work fulfils or mostly fulfils our styles and standards.
|
||||
|
||||
**New implementation** New implementation are welcome!
|
||||
|
||||
**Improving comments** and **adding tests** to existing algorithms are much appreciated.
|
||||
|
||||
**Issues** Please avoid opening issues asking to be "assigned” to a particular algorithm. This merely creates unnecessary noise for maintainers. Instead, please submit your implementation in a pull request and it will be evaluated by project maintainers.
|
||||
|
||||
### Making Changes
|
||||
|
||||
#### Code
|
||||
|
||||
22
DIRECTORY.md
22
DIRECTORY.md
@@ -4,6 +4,7 @@
|
||||
* [Knight Tour](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/knight_tour.cpp)
|
||||
* [Minimax](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/minimax.cpp)
|
||||
* [N Queens](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/n_queens.cpp)
|
||||
* [N Queens All Solution Optimised](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/n_queens_all_solution_optimised.cpp)
|
||||
* [Nqueen Print All Solutions](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/nqueen_print_all_solutions.cpp)
|
||||
* [Rat Maze](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/rat_maze.cpp)
|
||||
* [Sudoku Solve](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/sudoku_solve.cpp)
|
||||
@@ -13,6 +14,7 @@
|
||||
* [False-Position](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/computer_oriented_statistical_methods/false-position.cpp)
|
||||
* [Gaussian Elimination](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/computer_oriented_statistical_methods/Gaussian_elimination.cpp)
|
||||
* [Newton Raphson](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/computer_oriented_statistical_methods/Newton_Raphson.CPP)
|
||||
* [Ordinary Least Squares Regressor](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/computer_oriented_statistical_methods/ordinary_least_squares_regressor.cpp)
|
||||
* [Secant Method](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/computer_oriented_statistical_methods/Secant_method.CPP)
|
||||
* [Successive Approximation](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/computer_oriented_statistical_methods/successive_approximation.CPP)
|
||||
|
||||
@@ -26,7 +28,7 @@
|
||||
* [Cll](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/cll/cll.h)
|
||||
* [Main Cll](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/cll/main_cll.cpp)
|
||||
* [Disjoint Set](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/disjoint_set.cpp)
|
||||
* [Doubly Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/Doubly%20Linked%20List.cpp)
|
||||
* [Doubly Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/doubly_linked_list.cpp)
|
||||
* [Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/linked_list.cpp)
|
||||
* [Linkedlist Implentation Usingarray](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/linkedList_implentation_usingArray.cpp)
|
||||
* [List Array](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/List%20Array.cpp)
|
||||
@@ -72,13 +74,19 @@
|
||||
|
||||
## Graph
|
||||
* [Bfs](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/BFS.cpp)
|
||||
* [Bridge Finding With Tarjan Algorithm](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/bridge_finding_with_tarjan_algorithm.cpp)
|
||||
* [Connected Components](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/connected_components.cpp)
|
||||
* [Connected Components With Dsu](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/connected_components_with_dsu.cpp)
|
||||
* [Dfs](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/DFS.cpp)
|
||||
* [Dfs With Stack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/DFS_with_stack.cc)
|
||||
* [Dijkstra](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/Dijkstra.cpp)
|
||||
* [Kosaraju](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/kosaraju.cpp)
|
||||
* [Kruskal](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/Kruskal.cpp)
|
||||
* [Lca](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/lca.cpp)
|
||||
* [Max Flow With Ford Fulkerson And Edmond Karp Algo](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/max_flow_with_ford_fulkerson_and_edmond_karp_algo.cpp)
|
||||
* [Prim](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/prim.cpp)
|
||||
* [Topological-Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/Topological-Sort.cpp)
|
||||
* [Topological Sort By Kahns Algo](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/topological_sort_by_kahns_algo.cpp)
|
||||
|
||||
## Greedy Algorithms
|
||||
* [Dijkstra](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/greedy_algorithms/Dijkstra.cpp)
|
||||
@@ -95,9 +103,12 @@
|
||||
|
||||
## Math
|
||||
* [Binary Exponent](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/binary_exponent.cpp)
|
||||
* [Double Factorial](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/double_factorial.cpp)
|
||||
* [Eulers Totient Function](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/eulers_totient_function.cpp)
|
||||
* [Extended Euclid Algorithm](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/extended_euclid_algorithm.cpp)
|
||||
* [Factorial](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/factorial.cpp)
|
||||
* [Fast Power](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/fast_power.cpp)
|
||||
* [Fibonacci](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/fibonacci.cpp)
|
||||
* [Greatest Common Divisor](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/greatest_common_divisor.cpp)
|
||||
* [Greatest Common Divisor Euclidean](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/greatest_common_divisor_euclidean.cpp)
|
||||
* [Modular Inverse Fermat Little Theorem](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/modular_inverse_fermat_little_theorem.cpp)
|
||||
@@ -114,6 +125,7 @@
|
||||
* [Array Right Rotation](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/Array%20Right%20Rotation.cpp)
|
||||
* [Circular Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/Circular%20Linked%20List.cpp)
|
||||
* [Circular Queue Using Array](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/Circular%20Queue%20Using%20Array.cpp)
|
||||
* [Get Size Of Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/get_size_of_linked_list.cpp)
|
||||
* [Intersection Of 2 Arrays](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/Intersection_of_2_arrays.cpp)
|
||||
* [Reverse A Linked List Using Recusion](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/Reverse%20a%20Linked%20List%20using%20Recusion.cpp)
|
||||
* [Selectionsortlinkedlist](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/selectionSortLinkedList.cpp)
|
||||
@@ -146,6 +158,9 @@
|
||||
|
||||
## Probability
|
||||
* [Addition Rule](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/probability/addition_rule.cpp)
|
||||
* [Bayes Theorem](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/probability/bayes_theorem.cpp)
|
||||
* [Binomial Dist](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/probability/binomial_dist.cpp)
|
||||
* [Poisson Dist](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/probability/poisson_dist.cpp)
|
||||
|
||||
## Range Queries
|
||||
* [Bit](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/range_queries/bit.cpp)
|
||||
@@ -154,11 +169,12 @@
|
||||
* [Segtree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/range_queries/segTree.cpp)
|
||||
|
||||
## Search
|
||||
* [Binary Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/Binary%20Search.cpp)
|
||||
* [Binary Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/binary_search.cpp)
|
||||
* [Exponential Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/exponential_search.cpp)
|
||||
* [Hash Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/hash_search.cpp)
|
||||
* [Interpolation Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/Interpolation%20Search.cpp)
|
||||
* [Interpolation Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/interpolation_search.cpp)
|
||||
* [Jump Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/jump_search.cpp)
|
||||
* [Linear Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/Linear%20Search.cpp)
|
||||
* [Median Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/median_search.cpp)
|
||||
* [Searching](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/searching.cpp)
|
||||
@@ -185,8 +201,10 @@
|
||||
* [Selection Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/Selection%20Sort.cpp)
|
||||
* [Shell Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/Shell%20Sort.cpp)
|
||||
* [Slow Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/Slow%20Sort.cpp)
|
||||
* [Swap Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/swap_sort.cpp)
|
||||
* [Tim Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/Tim%20Sort.cpp)
|
||||
|
||||
## Strings
|
||||
* [Brute Force String Searching](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/strings/brute_force_string_searching.cpp)
|
||||
* [Knuth Morris Pratt](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/strings/knuth_morris_pratt.cpp)
|
||||
* [Rabin Karp](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/strings/rabin_karp.cpp)
|
||||
|
||||
75
backtracking/n_queens_all_solution_optimised.cpp
Normal file
75
backtracking/n_queens_all_solution_optimised.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#include <iostream>
|
||||
#define n 4
|
||||
#define inc_loop(var, start, stop) for (int var=start; var <= stop; var++)
|
||||
#define dec_loop(var, start, stop) for (int var=start; var >= stop; var--)
|
||||
void PrintSol(int Board[n][n]) {
|
||||
inc_loop(i, 0, n-1) {
|
||||
inc_loop(j, 0, n-1)
|
||||
std::cout << Board[i][j] << " ";
|
||||
std::cout << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
if (n%2 == 0 || (n%2 == 1 && Board[n/2+1][0] != 1)) {
|
||||
inc_loop(i, 0, n-1) {
|
||||
dec_loop(j, n-1, 0)
|
||||
std::cout << Board[i][j] << " ";
|
||||
std::cout << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
bool CanIMove(int Board[n][n], int row, int col) {
|
||||
/// check in the row
|
||||
inc_loop(i, 0, col-1) {
|
||||
if (Board[row][i] == 1)
|
||||
return false;
|
||||
}
|
||||
/// check the first diagonal
|
||||
for (int i = row, j = col; i >= 0 && j >= 0; i--, j--) {
|
||||
if (Board[i][j] == 1)
|
||||
return false;
|
||||
}
|
||||
/// check the second diagonal
|
||||
for (int i = row, j = col; i <= n - 1 && j >= 0; i++, j--) {
|
||||
if (Board[i][j] == 1)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void NQueenSol(int Board[n][n], int col) {
|
||||
if (col >= n) {
|
||||
PrintSol(Board);
|
||||
return;
|
||||
}
|
||||
inc_loop(i, 0, n-1) {
|
||||
if (CanIMove(Board, i, col)) {
|
||||
Board[i][col] = 1;
|
||||
NQueenSol(Board, col + 1);
|
||||
Board[i][col] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
int Board[n][n] = {0};
|
||||
if (n%2 == 0) {
|
||||
inc_loop(i, 0, n/2-1) {
|
||||
if (CanIMove(Board, i, 0)) {
|
||||
Board[i][0] = 1;
|
||||
NQueenSol(Board, 1);
|
||||
Board[i][0] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
inc_loop(i, 0, n/2) {
|
||||
if (CanIMove(Board, i, 0)) {
|
||||
Board[i][0] = 1;
|
||||
NQueenSol(Board, 1);
|
||||
Board[i][0] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
/**
|
||||
* Program that gets the number of data samples and number of features per
|
||||
* sample along with output per sample. It applies OLS regression to compute
|
||||
* the regression output for additional test data samples.
|
||||
**/
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
template <typename T>
|
||||
std::ostream &operator<<(std::ostream &out,
|
||||
std::vector<std::vector<T>> const &v) {
|
||||
const int width = 10;
|
||||
const char separator = ' ';
|
||||
|
||||
for (size_t row = 0; row < v.size(); row++) {
|
||||
for (size_t col = 0; col < v[row].size(); col++)
|
||||
out << std::left << std::setw(width) << std::setfill(separator)
|
||||
<< v[row][col];
|
||||
out << std::endl;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::ostream &operator<<(std::ostream &out, std::vector<T> const &v) {
|
||||
const int width = 15;
|
||||
const char separator = ' ';
|
||||
|
||||
for (size_t row = 0; row < v.size(); row++)
|
||||
out << std::left << std::setw(width) << std::setfill(separator) << v[row];
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool is_square(std::vector<std::vector<T>> const &A) {
|
||||
// Assuming A is square matrix
|
||||
size_t N = A.size();
|
||||
for (size_t i = 0; i < N; i++)
|
||||
if (A[i].size() != N)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* matrix multiplication
|
||||
**/
|
||||
template <typename T>
|
||||
std::vector<std::vector<T>> operator*(std::vector<std::vector<T>> const &A,
|
||||
std::vector<std::vector<T>> const &B) {
|
||||
// Number of rows in A
|
||||
size_t N_A = A.size();
|
||||
// Number of columns in B
|
||||
size_t N_B = B[0].size();
|
||||
|
||||
std::vector<std::vector<T>> result(N_A);
|
||||
|
||||
if (A[0].size() != B.size()) {
|
||||
std::cerr << "Number of columns in A != Number of rows in B ("
|
||||
<< A[0].size() << ", " << B.size() << ")" << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
for (size_t row = 0; row < N_A; row++) {
|
||||
std::vector<T> v(N_B);
|
||||
for (size_t col = 0; col < N_B; col++) {
|
||||
v[col] = static_cast<T>(0);
|
||||
for (size_t j = 0; j < B.size(); j++)
|
||||
v[col] += A[row][j] * B[j][col];
|
||||
}
|
||||
result[row] = v;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::vector<T> operator*(std::vector<std::vector<T>> const &A,
|
||||
std::vector<T> const &B) {
|
||||
// Number of rows in A
|
||||
size_t N_A = A.size();
|
||||
|
||||
std::vector<T> result(N_A);
|
||||
|
||||
if (A[0].size() != B.size()) {
|
||||
std::cerr << "Number of columns in A != Number of rows in B ("
|
||||
<< A[0].size() << ", " << B.size() << ")" << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
for (size_t row = 0; row < N_A; row++) {
|
||||
result[row] = static_cast<T>(0);
|
||||
for (size_t j = 0; j < B.size(); j++)
|
||||
result[row] += A[row][j] * B[j];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::vector<float> operator*(float const scalar, std::vector<T> const &A) {
|
||||
// Number of rows in A
|
||||
size_t N_A = A.size();
|
||||
|
||||
std::vector<float> result(N_A);
|
||||
|
||||
for (size_t row = 0; row < N_A; row++) {
|
||||
result[row] += A[row] * static_cast<float>(scalar);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::vector<float> operator*(std::vector<T> const &A, float const scalar) {
|
||||
// Number of rows in A
|
||||
size_t N_A = A.size();
|
||||
|
||||
std::vector<float> result(N_A);
|
||||
|
||||
for (size_t row = 0; row < N_A; row++)
|
||||
result[row] = A[row] * static_cast<float>(scalar);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::vector<float> operator/(std::vector<T> const &A, float const scalar) {
|
||||
return (1.f / scalar) * A;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::vector<T> operator-(std::vector<T> const &A, std::vector<T> const &B) {
|
||||
// Number of rows in A
|
||||
size_t N = A.size();
|
||||
|
||||
std::vector<T> result(N);
|
||||
|
||||
if (B.size() != N) {
|
||||
std::cerr << "Vector dimensions shouldbe identical!" << std::endl;
|
||||
return A;
|
||||
}
|
||||
|
||||
for (size_t row = 0; row < N; row++)
|
||||
result[row] = A[row] - B[row];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::vector<T> operator+(std::vector<T> const &A, std::vector<T> const &B) {
|
||||
// Number of rows in A
|
||||
size_t N = A.size();
|
||||
|
||||
std::vector<T> result(N);
|
||||
|
||||
if (B.size() != N) {
|
||||
std::cerr << "Vector dimensions shouldbe identical!" << std::endl;
|
||||
return A;
|
||||
}
|
||||
|
||||
for (size_t row = 0; row < N; row++)
|
||||
result[row] = A[row] + B[row];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get matrix inverse using Row-trasnformations
|
||||
**/
|
||||
template <typename T>
|
||||
std::vector<std::vector<float>>
|
||||
get_inverse(std::vector<std::vector<T>> const &A) {
|
||||
// Assuming A is square matrix
|
||||
size_t N = A.size();
|
||||
|
||||
std::vector<std::vector<float>> inverse(N);
|
||||
for (size_t row = 0; row < N; row++) {
|
||||
// preallocatae a resultant identity matrix
|
||||
inverse[row] = std::vector<float>(N);
|
||||
for (size_t col = 0; col < N; col++)
|
||||
inverse[row][col] = (row == col) ? 1.f : 0.f;
|
||||
}
|
||||
|
||||
if (!is_square(A)) {
|
||||
std::cerr << "A must be a square matrix!" << std::endl;
|
||||
return inverse;
|
||||
}
|
||||
|
||||
// preallocatae a temporary matrix identical to A
|
||||
std::vector<std::vector<float>> temp(N);
|
||||
for (size_t row = 0; row < N; row++) {
|
||||
std::vector<float> v(N);
|
||||
for (size_t col = 0; col < N; col++)
|
||||
v[col] = static_cast<float>(A[row][col]);
|
||||
temp[row] = v;
|
||||
}
|
||||
|
||||
// start transformations
|
||||
for (size_t row = 0; row < N; row++) {
|
||||
for (size_t row2 = row; row2 < N && temp[row][row] == 0; row2++) {
|
||||
// this to ensure diagonal elements are not 0
|
||||
temp[row] = temp[row] + temp[row2];
|
||||
inverse[row] = inverse[row] + inverse[row2];
|
||||
}
|
||||
|
||||
for (size_t col2 = row; col2 < N && temp[row][row] == 0; col2++) {
|
||||
// this to further ensure diagonal elements are not 0
|
||||
for (size_t row2 = 0; row2 < N; row2++) {
|
||||
temp[row2][row] = temp[row2][row] + temp[row2][col2];
|
||||
inverse[row2][row] = inverse[row2][row] + inverse[row2][col2];
|
||||
}
|
||||
}
|
||||
|
||||
if (temp[row][row] == 0) {
|
||||
// Probably a low-rank matrix and hence singular
|
||||
std::cerr << "Low-rank matrix, no inverse!" << std::endl;
|
||||
return inverse;
|
||||
}
|
||||
|
||||
// set diagonal to 1
|
||||
float divisor = static_cast<float>(temp[row][row]);
|
||||
temp[row] = temp[row] / divisor;
|
||||
inverse[row] = inverse[row] / divisor;
|
||||
// Row transformations
|
||||
for (size_t row2 = 0; row2 < N; row2++) {
|
||||
if (row2 == row)
|
||||
continue;
|
||||
float factor = temp[row2][row];
|
||||
temp[row2] = temp[row2] - factor * temp[row];
|
||||
inverse[row2] = inverse[row2] - factor * inverse[row];
|
||||
}
|
||||
}
|
||||
|
||||
return inverse;
|
||||
}
|
||||
|
||||
/**
|
||||
* matrix transpose
|
||||
**/
|
||||
template <typename T>
|
||||
std::vector<std::vector<T>>
|
||||
get_transpose(std::vector<std::vector<T>> const &A) {
|
||||
std::vector<std::vector<T>> result(A[0].size());
|
||||
|
||||
for (size_t row = 0; row < A[0].size(); row++) {
|
||||
std::vector<T> v(A.size());
|
||||
for (size_t col = 0; col < A.size(); col++)
|
||||
v[col] = A[col][row];
|
||||
|
||||
result[row] = v;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::vector<float> fit_OLS_regressor(std::vector<std::vector<T>> const &X,
|
||||
std::vector<T> const &Y) {
|
||||
// NxF
|
||||
std::vector<std::vector<T>> X2 = X;
|
||||
for (size_t i = 0; i < X2.size(); i++)
|
||||
// add Y-intercept -> Nx(F+1)
|
||||
X2[i].push_back(1);
|
||||
// (F+1)xN
|
||||
std::vector<std::vector<T>> Xt = get_transpose(X2);
|
||||
// (F+1)x(F+1)
|
||||
std::vector<std::vector<T>> tmp = get_inverse(Xt * X2);
|
||||
// (F+1)xN
|
||||
std::vector<std::vector<float>> out = tmp * Xt;
|
||||
// cout << endl
|
||||
// << "Projection matrix: " << X2 * out << endl;
|
||||
|
||||
// Fx1,1 -> (F+1)^th element is the independent constant
|
||||
return out * Y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given data and OLS model coeffficients, predict
|
||||
* regression estimates
|
||||
**/
|
||||
template <typename T>
|
||||
std::vector<float> predict_OLS_regressor(std::vector<std::vector<T>> const &X,
|
||||
std::vector<float> const &beta) {
|
||||
std::vector<float> result(X.size());
|
||||
|
||||
for (size_t rows = 0; rows < X.size(); rows++) {
|
||||
// -> start with constant term
|
||||
result[rows] = beta[X[0].size()];
|
||||
for (size_t cols = 0; cols < X[0].size(); cols++)
|
||||
result[rows] += beta[cols] * X[rows][cols];
|
||||
}
|
||||
// Nx1
|
||||
return result;
|
||||
}
|
||||
|
||||
int main() {
|
||||
size_t N, F;
|
||||
|
||||
std::cout << "Enter number of features: ";
|
||||
// number of features = columns
|
||||
std::cin >> F;
|
||||
std::cout << "Enter number of samples: ";
|
||||
// number of samples = rows
|
||||
std::cin >> N;
|
||||
|
||||
std::vector<std::vector<float>> data(N);
|
||||
std::vector<float> Y(N);
|
||||
|
||||
std::cout
|
||||
<< "Enter training data. Per sample, provide features ad one output."
|
||||
<< std::endl;
|
||||
|
||||
for (size_t rows = 0; rows < N; rows++) {
|
||||
std::vector<float> v(F);
|
||||
std::cout << "Sample# " << rows + 1 << ": ";
|
||||
for (size_t cols = 0; cols < F; cols++)
|
||||
// get the F features
|
||||
std::cin >> v[cols];
|
||||
data[rows] = v;
|
||||
// get the corresponding output
|
||||
std::cin >> Y[rows];
|
||||
}
|
||||
|
||||
std::vector<float> beta = fit_OLS_regressor(data, Y);
|
||||
std::cout << std::endl << std::endl << "beta:" << beta << std::endl;
|
||||
|
||||
size_t T;
|
||||
std::cout << "Enter number of test samples: ";
|
||||
// number of test sample inputs
|
||||
std::cin >> T;
|
||||
std::vector<std::vector<float>> data2(T);
|
||||
// vector<float> Y2(T);
|
||||
|
||||
for (size_t rows = 0; rows < T; rows++) {
|
||||
std::cout << "Sample# " << rows + 1 << ": ";
|
||||
std::vector<float> v(F);
|
||||
for (size_t cols = 0; cols < F; cols++)
|
||||
std::cin >> v[cols];
|
||||
data2[rows] = v;
|
||||
}
|
||||
|
||||
std::vector<float> out = predict_OLS_regressor(data2, beta);
|
||||
for (size_t rows = 0; rows < T; rows++)
|
||||
std::cout << out[rows] << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
struct node
|
||||
{
|
||||
int val;
|
||||
node *prev;
|
||||
node *next;
|
||||
};
|
||||
|
||||
node *start;
|
||||
|
||||
void insert(int x)
|
||||
{
|
||||
node *t = start;
|
||||
if (start != NULL)
|
||||
{
|
||||
while (t->next != NULL)
|
||||
{
|
||||
t = t->next;
|
||||
}
|
||||
node *n = new node;
|
||||
t->next = n;
|
||||
n->prev = t;
|
||||
n->val = x;
|
||||
n->next = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
node *n = new node;
|
||||
n->val = x;
|
||||
n->prev = NULL;
|
||||
n->next = NULL;
|
||||
start = n;
|
||||
}
|
||||
}
|
||||
|
||||
void remove(int x)
|
||||
{
|
||||
node *t = start;
|
||||
while (t->val != x)
|
||||
{
|
||||
t = t->next;
|
||||
}
|
||||
t->prev->next = t->next;
|
||||
t->next->prev = t->prev;
|
||||
delete t;
|
||||
}
|
||||
|
||||
void search(int x)
|
||||
{
|
||||
node *t = start;
|
||||
int found = 0;
|
||||
while (t != NULL)
|
||||
{
|
||||
if (t->val == x)
|
||||
{
|
||||
cout << "\nFound";
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
t = t->next;
|
||||
}
|
||||
if (found == 0)
|
||||
{
|
||||
cout << "\nNot Found";
|
||||
}
|
||||
}
|
||||
|
||||
void show()
|
||||
{
|
||||
node *t = start;
|
||||
while (t != NULL)
|
||||
{
|
||||
cout << t->val << "\t";
|
||||
t = t->next;
|
||||
}
|
||||
}
|
||||
|
||||
void reverseShow()
|
||||
{
|
||||
node *t = start;
|
||||
while (t->next != NULL)
|
||||
{
|
||||
t = t->next;
|
||||
}
|
||||
while (t != NULL)
|
||||
{
|
||||
cout << t->val << "\t";
|
||||
t = t->prev;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int choice, x;
|
||||
do
|
||||
{
|
||||
cout << "\n1. Insert";
|
||||
cout << "\n2. Delete";
|
||||
cout << "\n3. Search";
|
||||
cout << "\n4. Forward print";
|
||||
cout << "\n5. Reverse print";
|
||||
cout << "\n\nEnter you choice : ";
|
||||
cin >> choice;
|
||||
switch (choice)
|
||||
{
|
||||
case 1:
|
||||
cout << "\nEnter the element to be inserted : ";
|
||||
cin >> x;
|
||||
;
|
||||
insert(x);
|
||||
break;
|
||||
case 2:
|
||||
cout << "\nEnter the element to be removed : ";
|
||||
cin >> x;
|
||||
remove(x);
|
||||
break;
|
||||
case 3:
|
||||
cout << "\nEnter the element to be searched : ";
|
||||
cin >> x;
|
||||
search(x);
|
||||
break;
|
||||
case 4:
|
||||
show();
|
||||
break;
|
||||
case 5:
|
||||
reverseShow();
|
||||
break;
|
||||
}
|
||||
} while (choice != 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
138
data_structure/doubly_linked_list.cpp
Normal file
138
data_structure/doubly_linked_list.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
#include <iostream>
|
||||
#include<cstdio>
|
||||
#include<cstdlib>
|
||||
|
||||
struct node {
|
||||
int val;
|
||||
node *prev;
|
||||
node *next;
|
||||
}*start;
|
||||
|
||||
class double_linked_list {
|
||||
public:
|
||||
double_linked_list() {
|
||||
start = NULL;
|
||||
}
|
||||
void insert(int x);
|
||||
void remove(int x);
|
||||
void search(int x);
|
||||
void show();
|
||||
void reverseShow();
|
||||
};
|
||||
|
||||
void double_linked_list::insert(int x) {
|
||||
node *t = start;
|
||||
if (start != NULL) {
|
||||
while (t->next != NULL) {
|
||||
t = t->next;
|
||||
}
|
||||
node *n = new node;
|
||||
t->next = n;
|
||||
n->prev = t;
|
||||
n->val = x;
|
||||
n->next = NULL;
|
||||
} else {
|
||||
node *n = new node;
|
||||
n->val = x;
|
||||
n->prev = NULL;
|
||||
n->next = NULL;
|
||||
start = n;
|
||||
}
|
||||
}
|
||||
|
||||
void double_linked_list::remove(int x) {
|
||||
node *t = start;
|
||||
while (t != NULL && t->val != x) {
|
||||
t = t-> next;
|
||||
}
|
||||
if (t == NULL) {
|
||||
return;
|
||||
}
|
||||
if (t->prev == NULL) {
|
||||
if (t->next == NULL) {
|
||||
start = NULL;
|
||||
} else {
|
||||
start = t->next;
|
||||
start->prev = NULL;
|
||||
}
|
||||
} else if (t->next == NULL) {
|
||||
t->prev->next = NULL;
|
||||
} else {
|
||||
t->prev->next = t->next;
|
||||
t->next->prev = t->prev;
|
||||
}
|
||||
delete t;
|
||||
}
|
||||
|
||||
void double_linked_list::search(int x) {
|
||||
node *t = start;
|
||||
int found = 0;
|
||||
while (t != NULL) {
|
||||
if (t->val == x) {
|
||||
std::cout << "\nFound";
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
t = t->next;
|
||||
}
|
||||
if (found == 0) {
|
||||
std::cout << "\nNot Found";
|
||||
}
|
||||
}
|
||||
|
||||
void double_linked_list::show() {
|
||||
node *t = start;
|
||||
while (t != NULL) {
|
||||
std::cout << t->val << "\t";
|
||||
t = t->next;
|
||||
}
|
||||
}
|
||||
|
||||
void double_linked_list::reverseShow() {
|
||||
node *t = start;
|
||||
while (t != NULL && t->next != NULL) {
|
||||
t = t->next;
|
||||
}
|
||||
while (t != NULL) {
|
||||
std::cout << t->val << "\t";
|
||||
t = t->prev;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
int choice, x;
|
||||
double_linked_list ob;
|
||||
do {
|
||||
std::cout << "\n1. Insert";
|
||||
std::cout << "\n2. Delete";
|
||||
std::cout << "\n3. Search";
|
||||
std::cout << "\n4. Forward print";
|
||||
std::cout << "\n5. Reverse print";
|
||||
std::cout << "\n\nEnter you choice : ";
|
||||
std::cin >> choice;
|
||||
switch (choice) {
|
||||
case 1:
|
||||
std::cout << "\nEnter the element to be inserted : ";
|
||||
std::cin >> x;
|
||||
ob.insert(x);
|
||||
break;
|
||||
case 2:
|
||||
std::cout << "\nEnter the element to be removed : ";
|
||||
std::cin >> x;
|
||||
ob.remove(x);
|
||||
break;
|
||||
case 3:
|
||||
std::cout << "\nEnter the element to be searched : ";
|
||||
std::cin >> x;
|
||||
ob.search(x);
|
||||
break;
|
||||
case 4:
|
||||
ob.show();
|
||||
break;
|
||||
case 5:
|
||||
ob.reverseShow();
|
||||
break;
|
||||
}
|
||||
} while (choice != 0);
|
||||
return 0;
|
||||
}
|
||||
79
graph/bridge_finding_with_tarjan_algorithm.cpp
Normal file
79
graph/bridge_finding_with_tarjan_algorithm.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright : 2020 , MIT
|
||||
* Author : Amit Kumar (offamitkumar)
|
||||
* Last Modified Date: May 24, 2020
|
||||
*
|
||||
*/
|
||||
#include <vector> // for std::vector
|
||||
#include <algorithm> // for min & max
|
||||
#include <iostream> // for cout
|
||||
using std::vector;
|
||||
using std::cout;
|
||||
using std::min;
|
||||
class Solution {
|
||||
vector < vector < int > > graph;
|
||||
vector<int>in_time , out_time;
|
||||
int timer;
|
||||
vector < vector < int > > bridge;
|
||||
vector<bool>visited;
|
||||
void dfs(int current_node , int parent) {
|
||||
visited.at(current_node) = true;
|
||||
in_time[current_node] = out_time[current_node] = timer++;
|
||||
for ( auto&itr : graph[current_node] ) {
|
||||
if (itr == parent) {
|
||||
continue;
|
||||
}
|
||||
if (!visited[itr]) {
|
||||
dfs(itr , current_node);
|
||||
if (out_time[itr] > in_time[current_node]) {
|
||||
bridge.push_back({itr, current_node});
|
||||
}
|
||||
}
|
||||
out_time[current_node] = min(out_time[current_node], out_time[itr]);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
vector <vector <int> > search_bridges(int n,
|
||||
const vector<vector<int>>& connections) {
|
||||
timer = 0;
|
||||
graph.resize(n);
|
||||
in_time.assign(n, 0);
|
||||
visited.assign(n, false);
|
||||
out_time.assign(n, 0);
|
||||
for (auto&itr : connections) {
|
||||
graph.at(itr[0]).push_back(itr[1]);
|
||||
graph.at(itr[1]).push_back(itr[0]);
|
||||
}
|
||||
dfs(0, -1);
|
||||
return bridge;
|
||||
}
|
||||
};
|
||||
int main(void) {
|
||||
Solution s1;
|
||||
int number_of_node = 5;
|
||||
vector< vector <int> >node;
|
||||
node.push_back({0, 1});
|
||||
node.push_back({1, 3});
|
||||
node.push_back({1, 2});
|
||||
node.push_back({2, 4});
|
||||
/*
|
||||
* 0 <--> 1 <---> 2
|
||||
* ^ ^
|
||||
* | |
|
||||
* | |
|
||||
* \/ \/
|
||||
* 3 4
|
||||
*
|
||||
* In this graph there are 4 bridges [0,2] , [2,4] , [3,5] , [1,2]
|
||||
*
|
||||
* I assumed that the graph is bi-directional and connected.
|
||||
*
|
||||
*/
|
||||
vector< vector <int> > bridges = s1.search_bridges(number_of_node , node);
|
||||
cout << bridges.size() << " bridges found!\n";
|
||||
for (auto&itr : bridges) {
|
||||
cout << itr[0] << " --> " << itr[1] << '\n';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
55
graph/connected_components_with_dsu.cpp
Normal file
55
graph/connected_components_with_dsu.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
int N; // denotes number of nodes;
|
||||
std::vector<int> parent;
|
||||
std::vector<int> siz;
|
||||
void make_set() { // function the initialize every node as it's own parent
|
||||
for (int i = 1; i <= N; i++) {
|
||||
parent[i] = i;
|
||||
siz[i] = 1;
|
||||
}
|
||||
}
|
||||
// To find the component where following node belongs to
|
||||
int find_set(int v) {
|
||||
if (v == parent[v])
|
||||
return v;
|
||||
return parent[v] = find_set(parent[v]);
|
||||
}
|
||||
|
||||
void union_sets(int a, int b) { // To join 2 components to belong to one
|
||||
a = find_set(a);
|
||||
b = find_set(b);
|
||||
if (a != b) {
|
||||
if (siz[a] < siz[b])
|
||||
std::swap(a, b);
|
||||
parent[b] = a;
|
||||
siz[a] += siz[b];
|
||||
}
|
||||
}
|
||||
|
||||
int no_of_connected_components() { // To find total no of connected components
|
||||
std::set<int> temp; // temp set to count number of connected components
|
||||
for (int i = 1; i <= N; i++)
|
||||
temp.insert(find_set(i));
|
||||
return temp.size();
|
||||
}
|
||||
|
||||
// All critical/corner cases have been taken care of.
|
||||
// Input your required values: (not hardcoded)
|
||||
int main() {
|
||||
std::cin >> N;
|
||||
parent.resize(N + 1);
|
||||
siz.resize(N + 1);
|
||||
make_set();
|
||||
int edges;
|
||||
std::cin >> edges; // no of edges in the graph
|
||||
while (edges--) {
|
||||
int node_a, node_b;
|
||||
std::cin >> node_a >> node_b;
|
||||
union_sets(node_a, node_b);
|
||||
}
|
||||
std::cout << no_of_connected_components() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
122
graph/max_flow_with_ford_fulkerson_and_edmond_karp_algo.cpp
Normal file
122
graph/max_flow_with_ford_fulkerson_and_edmond_karp_algo.cpp
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Author: Amit Kumar
|
||||
* Created: May 24, 2020
|
||||
* Copyright: 2020, Open-Source
|
||||
* Last Modified: May 25, 2020
|
||||
*/
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
#include <tuple>
|
||||
#include <algorithm>
|
||||
#include <bitset>
|
||||
#include <limits>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
// std::max capacity of node in graph
|
||||
const int MAXN = 505;
|
||||
class Graph {
|
||||
int residual_capacity[MAXN][MAXN];
|
||||
int capacity[MAXN][MAXN]; // used while checking the flow of edge
|
||||
int total_nodes;
|
||||
int total_edges, source, sink;
|
||||
int parent[MAXN];
|
||||
std::vector <std::tuple <int, int, int> >edge_participated;
|
||||
std::bitset <MAXN> visited;
|
||||
int max_flow = 0;
|
||||
bool bfs(int source, int sink) { // to find the augmented - path
|
||||
memset(parent, -1, sizeof(parent));
|
||||
visited.reset();
|
||||
std::queue<int>q;
|
||||
q.push(source);
|
||||
bool is_path_found = false;
|
||||
while (q.empty() == false && is_path_found == false) {
|
||||
int current_node = q.front();
|
||||
visited.set(current_node);
|
||||
q.pop();
|
||||
for (int i = 0; i < total_nodes; ++i) {
|
||||
if (residual_capacity[current_node][i] > 0 && !visited[i]) {
|
||||
visited.set(i);
|
||||
parent[i] = current_node;
|
||||
if (i == sink) {
|
||||
return true;
|
||||
}
|
||||
q.push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
Graph() {
|
||||
memset(residual_capacity, 0, sizeof(residual_capacity));
|
||||
}
|
||||
void set_graph(void) {
|
||||
std::cin >> total_nodes >> total_edges >> source >> sink;
|
||||
for (int start, destination, capacity_, i = 0; i < total_edges; ++i) {
|
||||
std::cin >> start >> destination >> capacity_;
|
||||
residual_capacity[start][destination] = capacity_;
|
||||
capacity[start][destination] = capacity_;
|
||||
}
|
||||
}
|
||||
void ford_fulkerson(void) {
|
||||
while (bfs(source, sink)) {
|
||||
int current_node = sink;
|
||||
int flow = std::numeric_limits<int>::max();
|
||||
while (current_node != source) {
|
||||
int parent_ = parent[current_node];
|
||||
flow = std::min(flow, residual_capacity[parent_][current_node]);
|
||||
current_node = parent_;
|
||||
}
|
||||
current_node = sink;
|
||||
max_flow += flow;
|
||||
while ( current_node != source ) {
|
||||
int parent_ = parent[current_node];
|
||||
residual_capacity[parent_][current_node] -= flow;
|
||||
residual_capacity[current_node][parent_] += flow;
|
||||
current_node = parent_;
|
||||
}
|
||||
}
|
||||
}
|
||||
void print_flow_info(void) {
|
||||
for (int i = 0; i < total_nodes; ++i) {
|
||||
for (int j = 0; j < total_nodes; ++j) {
|
||||
if (capacity[i][j] &&
|
||||
residual_capacity[i][j] < capacity[i][j]) {
|
||||
edge_participated.push_back(
|
||||
std::make_tuple(i, j,
|
||||
capacity[i][j]-residual_capacity[i][j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << "\nNodes : " << total_nodes
|
||||
<< "\nMax flow: " << max_flow
|
||||
<< "\nEdge present in flow: " << edge_participated.size()
|
||||
<< '\n';
|
||||
std::cout<< "\nSource\tDestination\tCapacity\total_nodes";
|
||||
for (auto&edge_data : edge_participated) {
|
||||
int source, destination, capacity_;
|
||||
std::tie(source, destination, capacity_) = edge_data;
|
||||
std::cout << source << "\t" << destination << "\t\t"
|
||||
<< capacity_ <<'\t';
|
||||
}
|
||||
}
|
||||
};
|
||||
int main(void) {
|
||||
/*
|
||||
Input Graph: (for testing )
|
||||
4 5 0 3
|
||||
0 1 10
|
||||
1 2 1
|
||||
1 3 1
|
||||
0 2 1
|
||||
2 3 10
|
||||
*/
|
||||
Graph graph;
|
||||
graph.set_graph();
|
||||
graph.ford_fulkerson();
|
||||
graph.print_flow_info();
|
||||
return 0;
|
||||
}
|
||||
|
||||
58
graph/prim.cpp
Normal file
58
graph/prim.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
// C++ program to implement Prim's Algorithm
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
|
||||
const int MAX = 1e4 + 5;
|
||||
typedef std:: pair<int, int> PII;
|
||||
|
||||
bool marked[MAX];
|
||||
std:: vector <PII> adj[MAX];
|
||||
|
||||
int prim(int x) {
|
||||
// priority queue to maintain edges with respect to weights
|
||||
std:: priority_queue<PII, std:: vector<PII>, std:: greater<PII> > Q;
|
||||
int y;
|
||||
int minimumCost = 0;
|
||||
PII p;
|
||||
|
||||
Q.push(std:: make_pair(0, x));
|
||||
while (!Q.empty()) {
|
||||
// Select the edge with minimum weight
|
||||
p = Q.top();
|
||||
Q.pop();
|
||||
x = p.second;
|
||||
// Checking for cycle
|
||||
if (marked[x] == true)
|
||||
continue;
|
||||
minimumCost += p.first;
|
||||
marked[x] = true;
|
||||
for (int i = 0; i < adj[x].size(); ++i) {
|
||||
y = adj[x][i].second;
|
||||
if (marked[y] == false)
|
||||
Q.push(adj[x][i]);
|
||||
}
|
||||
}
|
||||
return minimumCost;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int nodes, edges, x, y;
|
||||
int weight, minimumCost;
|
||||
|
||||
std:: cin >> nodes >> edges; // number of nodes & edges in graph
|
||||
if (nodes == 0 || edges == 0)
|
||||
return 0;
|
||||
|
||||
// Edges with their nodes & weight
|
||||
for (int i = 0; i < edges; ++i) {
|
||||
std::cin >> x >> y >> weight;
|
||||
adj[x].push_back(std:: make_pair(weight, y));
|
||||
adj[y].push_back(std:: make_pair(weight, x));
|
||||
}
|
||||
|
||||
// Selecting 1 as the starting node
|
||||
minimumCost = prim(1);
|
||||
std:: cout << minimumCost << std:: endl;
|
||||
return 0;
|
||||
}
|
||||
68
graph/topological_sort_by_kahns_algo.cpp
Normal file
68
graph/topological_sort_by_kahns_algo.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
|
||||
int *topoSortKahn(int N, std::vector<int> adj[]);
|
||||
|
||||
int main() {
|
||||
int nodes, edges;
|
||||
std::cin >> edges >> nodes;
|
||||
if (edges == 0 || nodes == 0)
|
||||
return 0;
|
||||
int u, v;
|
||||
|
||||
std::vector<int>graph[nodes];
|
||||
// create graph
|
||||
// example
|
||||
// 6 6
|
||||
// 5 0 5 2 2 3 4 0 4 1 1 3
|
||||
|
||||
for (int i = 0; i < edges; i++) {
|
||||
std::cin >> u >> v;
|
||||
graph[u].push_back(v);
|
||||
}
|
||||
|
||||
int *topo = topoSortKahn(nodes, graph);
|
||||
// topologically sorted nodes
|
||||
for (int i = 0; i < nodes; i++) {
|
||||
std::cout << topo[i] << " ";
|
||||
}
|
||||
}
|
||||
|
||||
int* topoSortKahn(int V, std::vector<int> adj[]) {
|
||||
std::vector<bool>vis(V+1, false);
|
||||
std::vector<int>deg(V+1, 0);
|
||||
for (int i = 0; i < V; i++) {
|
||||
for (int j = 0; j < adj[i].size(); j++) {
|
||||
deg[adj[i][j]]++;
|
||||
}
|
||||
}
|
||||
std::queue<int>q;
|
||||
for (int i = 0; i < V; i++) {
|
||||
if (deg[i] == 0) {
|
||||
q.push(i);
|
||||
vis[i] = true;
|
||||
}
|
||||
}
|
||||
int *arr = new int[V+1];
|
||||
memset(arr, 0, V+1);
|
||||
int count = 0;
|
||||
while (!q.empty()) {
|
||||
int cur = q.front();
|
||||
q.pop();
|
||||
arr[count] = cur;
|
||||
count++;
|
||||
for (int i = 0; i < adj[cur].size(); i++) {
|
||||
if (!vis[adj[cur][i]]) {
|
||||
deg[adj[cur][i]]--;
|
||||
if (deg[adj[cur][i]] == 0) {
|
||||
q.push(adj[cur][i]);
|
||||
vis[adj[cur][i]] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
28
math/double_factorial.cpp
Normal file
28
math/double_factorial.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
|
||||
/* Double factorial of a non-negative integer n, is defined as the product of
|
||||
all the integers from 1 to n that have the same parity (odd or even) as n.
|
||||
It is also called as semifactorial of a number and is denoted by !! */
|
||||
|
||||
uint64_t double_factorial_iterative(uint64_t n) {
|
||||
uint64_t res = 1;
|
||||
for ( uint64_t i = n; i >= 0; i -= 2 ) {
|
||||
if (i == 0 || i == 1) return res;
|
||||
res *= i;
|
||||
}
|
||||
}
|
||||
|
||||
/* Recursion can be costly for large numbers */
|
||||
|
||||
uint64_t double_factorial_recursive(uint64_t n) {
|
||||
if (n <= 1) return 1;
|
||||
return n * double_factorial_recursive(n - 2);
|
||||
}
|
||||
|
||||
int main() {
|
||||
uint64_t n{};
|
||||
std::cin >> n;
|
||||
assert(n >= 0);
|
||||
std::cout << double_factorial_iterative(n);
|
||||
}
|
||||
28
math/extended_euclid_algorithm.cpp
Normal file
28
math/extended_euclid_algorithm.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include <iostream>
|
||||
// Finding coefficients of a and b ie x and y in gcd(a, b) = a * x + b * y
|
||||
// d is gcd(a, b)
|
||||
// This is also used in finding Modular multiplicative inverse of a number.
|
||||
// (A * B)%M == 1 Here B is the MMI of A for given M,
|
||||
// so extendedEuclid (A, M) gives B.
|
||||
|
||||
int d, x, y;
|
||||
void extendedEuclid(int A, int B) {
|
||||
if (B == 0) {
|
||||
d = A;
|
||||
x = 1;
|
||||
y = 0;
|
||||
} else {
|
||||
extendedEuclid(B, A%B);
|
||||
int temp = x;
|
||||
x = y;
|
||||
y = temp - (A/B)*y;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
int a, b;
|
||||
std::cin >> a >> b;
|
||||
extendedEuclid(a, b);
|
||||
std::cout << x << " " << y << std::endl;
|
||||
return 0;
|
||||
}
|
||||
25
math/fibonacci.cpp
Normal file
25
math/fibonacci.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
|
||||
/* Calculate the the value on Fibonacci's sequence given an
|
||||
integer as input
|
||||
Fibonacci = 0, 1, 1, 2, 3, 5,
|
||||
8, 13, 21, 34, 55,
|
||||
89, 144, ... */
|
||||
|
||||
int fibonacci(uint n) {
|
||||
/* If the input is 0 or 1 just return the same
|
||||
This will set the first 2 values of the sequence */
|
||||
if (n <= 1)
|
||||
return n;
|
||||
|
||||
/* Add the last 2 values of the sequence to get next */
|
||||
return fibonacci(n-1) + fibonacci(n-2);
|
||||
}
|
||||
|
||||
int main() {
|
||||
int n;
|
||||
std::cin >> n;
|
||||
assert(n >= 0);
|
||||
std::cout << "F(" << n << ")= " << fibonacci(n) << std::endl;
|
||||
}
|
||||
@@ -6,6 +6,9 @@ number in O(logn) time,
|
||||
with precision fixed */
|
||||
|
||||
double Sqrt(double x) {
|
||||
if ( x > 0 && x < 1 ) {
|
||||
return 1/Sqrt(1/x);
|
||||
}
|
||||
double l = 0, r = x;
|
||||
/* Epsilon is the precision.
|
||||
A great precision is
|
||||
|
||||
36
operations_on_datastructures/get_size_of_linked_list.cpp
Normal file
36
operations_on_datastructures/get_size_of_linked_list.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <iostream>
|
||||
|
||||
class Node {
|
||||
public:
|
||||
int val;
|
||||
Node *next;
|
||||
|
||||
Node(int v, Node *n) : val(v), next(n) {} // Default constructor for Node
|
||||
};
|
||||
|
||||
int getSize(Node *root) {
|
||||
if (root == NULL) {
|
||||
return 0;
|
||||
}
|
||||
// Each node will return 1 so the total adds up to be the size
|
||||
return 1 + getSize(root->next);
|
||||
}
|
||||
|
||||
int main() {
|
||||
Node *myList = new Node(0, NULL); // Initializes the LinkedList
|
||||
Node *temp = myList;
|
||||
// Creates a linked lists of total size 10, numbered 1 - 10
|
||||
for (int i = 1; i < 10; i++) {
|
||||
temp->next = new Node(i, NULL);
|
||||
temp = temp->next;
|
||||
}
|
||||
// Creating other lists for checking purposes
|
||||
Node *secondList = new Node(0, NULL); // List of size 1
|
||||
Node *thirdList = NULL; // List of size 0
|
||||
|
||||
std::cout << getSize(myList) << std::endl
|
||||
<< getSize(secondList) << std::endl
|
||||
<< getSize(thirdList) << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
30
probability/bayes_theorem.cpp
Normal file
30
probability/bayes_theorem.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include <iostream>
|
||||
|
||||
// bayes' theorem > https://en.wikipedia.org/wiki/Bayes%27_theorem
|
||||
|
||||
// bayes' theorem allows one to find P(A|B) given P(B|A)
|
||||
// or P(B|A) given P(A|B) and P(A) and P(B)
|
||||
|
||||
// note P(A|B) is read 'The probability of A given that the event B has occured'
|
||||
|
||||
// returns P(A|B)
|
||||
|
||||
double bayes_AgivenB(double BgivenA, double A, double B) {
|
||||
return (BgivenA * A) / B;
|
||||
}
|
||||
|
||||
// returns P(B|A)
|
||||
|
||||
double bayes_BgivenA(double AgivenB, double A, double B) {
|
||||
return (AgivenB * B) / A;
|
||||
}
|
||||
|
||||
int main() {
|
||||
double A = 0.01;
|
||||
double B = 0.1;
|
||||
double BgivenA = 0.9;
|
||||
double AgivenB = bayes_AgivenB(BgivenA, A, B);
|
||||
std::cout << "A given B = " << AgivenB << std::endl;
|
||||
std::cout << "B given A = " << bayes_BgivenA(AgivenB, A, B) << std::endl;
|
||||
return 0;
|
||||
}
|
||||
81
probability/binomial_dist.cpp
Normal file
81
probability/binomial_dist.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
// the binomial distribution models the number of
|
||||
// successes in a sequence of n independent events
|
||||
|
||||
// n : number of trials
|
||||
// p : probability of success
|
||||
// x : desired successes
|
||||
|
||||
// finds the expected value of a binomial distribution
|
||||
|
||||
double binomial_expected(double n, double p) {
|
||||
return n * p;
|
||||
}
|
||||
|
||||
// finds the variance of the binomial distribution
|
||||
|
||||
double binomial_variance(double n, double p) {
|
||||
return n * p * (1 - p);
|
||||
}
|
||||
|
||||
// finds the standard deviation of the binomial distribution
|
||||
|
||||
double binomial_standard_deviation(double n, double p) {
|
||||
return sqrt(binomial_variance(n, p));
|
||||
}
|
||||
|
||||
// Computes n choose r
|
||||
// n being the trials and r being the desired successes
|
||||
|
||||
double nCr(double n, double r) {
|
||||
double numerator = n;
|
||||
double denominator = r;
|
||||
|
||||
for (int i = n - 1 ; i >= ((n - r) + 1); i--) {
|
||||
numerator *= i;
|
||||
}
|
||||
|
||||
for (int i = 1; i < r ; i++) {
|
||||
denominator *= i;
|
||||
}
|
||||
|
||||
return numerator / denominator;
|
||||
}
|
||||
|
||||
// calculates the probability of exactly x successes
|
||||
|
||||
double binomial_x_successes(double n, double p, double x) {
|
||||
return nCr(n, x) * pow(p, x) * pow(1-p, n-x);
|
||||
}
|
||||
|
||||
// calculates the probability of a result within a range (inclusive, inclusive)
|
||||
|
||||
double binomial_range_successes(
|
||||
double n, double p, double lower_bound, double upper_bound) {
|
||||
double probability = 0;
|
||||
for (int i = lower_bound; i <= upper_bound; i++) {
|
||||
probability += nCr(n, i) * pow(p, i) * pow(1 - p, n - i);
|
||||
}
|
||||
return probability;
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::cout << "expected value : "
|
||||
<<binomial_expected(100, 0.5) << std::endl;
|
||||
|
||||
std::cout << "variance : "
|
||||
<< binomial_variance(100, 0.5) << std::endl;
|
||||
|
||||
std::cout << "standard deviation : "
|
||||
<< binomial_standard_deviation(100, 0.5) << std::endl;
|
||||
|
||||
std::cout << "exactly 30 successes : "
|
||||
<< binomial_x_successes(100, 0.5, 30) << std::endl;
|
||||
|
||||
std::cout << "45 or more successes : "
|
||||
<< binomial_range_successes(100, 0.5, 45, 100) << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
66
probability/poisson_dist.cpp
Normal file
66
probability/poisson_dist.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
// The Poisson distribution counts how many
|
||||
// events occur over a set time interval
|
||||
// https://en.wikipedia.org/wiki/Poisson_distribution
|
||||
|
||||
// calculate the events per unit time
|
||||
// e.g 5 dollars every 2 mins = 5 / 2 = 2.5
|
||||
|
||||
double poisson_rate(double events, double timeframe) {
|
||||
return events / timeframe;
|
||||
}
|
||||
|
||||
// calculate the expected value over a time
|
||||
// e.g rate of 2.5 over 10 mins = 2.5 x 10 = 25
|
||||
|
||||
double poisson_expected(double rate, double time) {
|
||||
return rate * time;
|
||||
}
|
||||
|
||||
// find the factorial of a given number
|
||||
|
||||
double fact(double x) {
|
||||
double x_fact = x;
|
||||
for (int i = x - 1; i > 0; i--) {
|
||||
x_fact *= i;
|
||||
}
|
||||
|
||||
if (x_fact <= 0) {
|
||||
x_fact = 1;
|
||||
}
|
||||
return x_fact;
|
||||
}
|
||||
|
||||
// find the probability of x successes in a Poisson dist
|
||||
|
||||
double poisson_x_successes(double expected, double x) {
|
||||
return (pow(expected, x) * exp(-expected)) / fact(x);
|
||||
}
|
||||
|
||||
// probability of a success in range for Poisson dist (inclusive, inclusive)
|
||||
|
||||
double poisson_range_successes(double expected, double lower, double upper) {
|
||||
double probability = 0;
|
||||
for (int i = lower; i <= upper; i++) {
|
||||
probability += poisson_x_successes(expected, i);
|
||||
}
|
||||
return probability;
|
||||
}
|
||||
|
||||
int main() {
|
||||
double rate, expected;
|
||||
rate = poisson_rate(3, 1);
|
||||
std::cout << "Poisson rate : " << rate << std::endl;
|
||||
|
||||
expected = poisson_expected(rate, 2);
|
||||
std::cout << "Poisson expected : " << expected << std::endl;
|
||||
|
||||
std::cout << "Poisson 0 successes : "
|
||||
<<poisson_x_successes(expected, 0) <<std::endl;
|
||||
std::cout << "Poisson 0-8 successes : "
|
||||
<< poisson_range_successes(expected, 0, 8) <<std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
int binary_search(int a[], int l, int r, int key)
|
||||
{
|
||||
while (l <= r)
|
||||
{
|
||||
int m = l + (r - l) / 2;
|
||||
if (key == a[m])
|
||||
return m;
|
||||
else if (key < a[m])
|
||||
r = m - 1;
|
||||
else
|
||||
l = m + 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
int n, key;
|
||||
cout << "Enter size of array: ";
|
||||
cin >> n;
|
||||
cout << "Enter array elements: ";
|
||||
int a[n];
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
cin >> a[i];
|
||||
}
|
||||
cout << "Enter search key: ";
|
||||
cin >> key;
|
||||
int res = binary_search(a, 0, n - 1, key);
|
||||
if (res != -1)
|
||||
cout << key << " found at index " << res << endl;
|
||||
else
|
||||
cout << key << " not found" << endl;
|
||||
return 0;
|
||||
}
|
||||
34
search/binary_search.cpp
Normal file
34
search/binary_search.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#include <iostream>
|
||||
// binary_search function
|
||||
int binary_search(int a[], int l, int r, int key) {
|
||||
while (l <= r) {
|
||||
int m = l + (r - l) / 2;
|
||||
if (key == a[m])
|
||||
return m;
|
||||
else if (key < a[m])
|
||||
r = m - 1;
|
||||
else
|
||||
l = m + 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
int main(int argc, char const* argv[]) {
|
||||
int n, key;
|
||||
std::cout << "Enter size of array: ";
|
||||
std::cin >> n;
|
||||
std::cout << "Enter array elements: ";
|
||||
int* a = new int[n];
|
||||
// this loop use for store value in Array
|
||||
for (int i = 0; i < n; i++) {
|
||||
std::cin >> a[i];
|
||||
}
|
||||
std::cout << "Enter search key: ";
|
||||
std::cin >> key;
|
||||
// this is use for find value in given array
|
||||
int res = binary_search(a, 0, n - 1, key);
|
||||
if (res != -1)
|
||||
std::cout << key << " found at index " << res << std::endl;
|
||||
else
|
||||
std::cout << key << " not found" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
54
search/jump_search.cpp
Normal file
54
search/jump_search.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
// C++ program to implement Jump Search
|
||||
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
int jumpSearch(int arr[], int x, int n)
|
||||
{
|
||||
// Finding block size to be jumped
|
||||
int step = sqrt(n);
|
||||
|
||||
// Finding the block where element is
|
||||
// present (if it is present)
|
||||
int prev = 0;
|
||||
while (arr[min(step, n)-1] < x)
|
||||
{
|
||||
prev = step;
|
||||
step += sqrt(n);
|
||||
if (prev >= n)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Doing a linear search for x in block
|
||||
// beginning with prev.
|
||||
while (arr[prev] < x)
|
||||
{
|
||||
prev++;
|
||||
|
||||
// If we reached next block or end of
|
||||
// array, element is not present.
|
||||
if (prev == min(step, n))
|
||||
return -1;
|
||||
}
|
||||
// If element is found
|
||||
if (arr[prev] == x)
|
||||
return prev;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Driver program to test function
|
||||
int main()
|
||||
{
|
||||
int arr[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21,
|
||||
34, 55, 89, 144, 233, 377, 610 };
|
||||
int x = 55;
|
||||
int n = sizeof(arr) / sizeof(arr[0]);
|
||||
|
||||
// Find the index of 'x' using Jump Search
|
||||
int index = jumpSearch(arr, x, n);
|
||||
|
||||
// Print the index where 'x' is located
|
||||
cout << "\nNumber " << x << " is at index " << index;
|
||||
return 0;
|
||||
}
|
||||
66
sorting/swap_sort.cpp
Normal file
66
sorting/swap_sort.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
// C++ program to find minimum number of swaps required to sort an array
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
// Function returns the minimum number of swaps
|
||||
// required to sort the array
|
||||
int minSwaps(int arr[], int n) {
|
||||
// Create an array of pairs where first
|
||||
// element is array element and second element
|
||||
// is position of first element
|
||||
std::pair<int, int> arrPos[n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
arrPos[i].first = arr[i];
|
||||
arrPos[i].second = i;
|
||||
}
|
||||
|
||||
// Sort the array by array element values to
|
||||
// get right position of every element as second
|
||||
// element of pair.
|
||||
std::sort(arrPos, arrPos + n);
|
||||
|
||||
// To keep track of visited elements. Initialize
|
||||
// all elements as not visited or false.
|
||||
std::vector<bool> vis(n, false);
|
||||
|
||||
// Initialize result
|
||||
int ans = 0;
|
||||
|
||||
// Traverse array elements
|
||||
for (int i = 0; i < n; i++) {
|
||||
// already swapped and corrected or
|
||||
// already present at correct pos
|
||||
if (vis[i] || arrPos[i].second == i)
|
||||
continue;
|
||||
|
||||
// find out the number of node in
|
||||
// this cycle and add in ans
|
||||
int cycle_size = 0;
|
||||
int j = i;
|
||||
while (!vis[j]) {
|
||||
vis[j] = 1;
|
||||
|
||||
// move to next node
|
||||
j = arrPos[j].second;
|
||||
cycle_size++;
|
||||
}
|
||||
|
||||
// Update answer by adding current cycle.
|
||||
if (cycle_size > 0) {
|
||||
ans += (cycle_size - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Return result
|
||||
return ans;
|
||||
}
|
||||
|
||||
// program to test
|
||||
int main() {
|
||||
int arr[] = {6, 7, 8, 1, 2, 3, 9, 12};
|
||||
int n = (sizeof(arr) / sizeof(int));
|
||||
std::cout << minSwaps(arr, n);
|
||||
return 0;
|
||||
}
|
||||
78
strings/rabin_karp.cpp
Normal file
78
strings/rabin_karp.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* file name : rabin_karp.cpp
|
||||
* author : Amit Kumar
|
||||
* Copyright : 2020 , Amit Kumar
|
||||
* version : 1.0
|
||||
*/
|
||||
#include<cassert>
|
||||
#include<cmath>
|
||||
#include<iostream>
|
||||
#include<string>
|
||||
|
||||
using std::string;
|
||||
using std::pow;
|
||||
|
||||
#define PRIME 5
|
||||
|
||||
int64_t create_hash(string s , int n) {
|
||||
int64_t result = 0;
|
||||
for ( int i = 0; i < n; ++i ) {
|
||||
result += (int64_t)(s[i] * (int64_t)pow(PRIME , i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int64_t recalculate_hash(string s , int old_index ,
|
||||
int new_index , int64_t old_hash , int patLength) {
|
||||
int64_t new_hash = old_hash - s[old_index];
|
||||
new_hash /= PRIME;
|
||||
new_hash += (int64_t)(s[new_index]*(int64_t)pow(PRIME, patLength-1));
|
||||
return new_hash;
|
||||
}
|
||||
|
||||
bool check_if_equal(string str1 , string str2 ,
|
||||
int start1 , int end1 ,
|
||||
int start2 , int end2) {
|
||||
if (end1-start1 != end2-start2) {
|
||||
return false;
|
||||
}
|
||||
while (start1 <= end1 && start2 <= end2) {
|
||||
if (str1[start1] != str2[start2]) {
|
||||
return false;
|
||||
}
|
||||
start1++;
|
||||
start2++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* @description : search pattern in the given text
|
||||
* @param : string str
|
||||
* @param : string pat
|
||||
* @return index of first occurrence of pattern or -1 if pattern not found
|
||||
*/
|
||||
|
||||
int rabin_karp(const string &str , const string& pat) {
|
||||
int64_t pat_hash = create_hash(pat , pat.size());
|
||||
int64_t str_hash = create_hash(str , pat.size());
|
||||
for (int i=0; i <= str.size()-pat.size(); ++i) {
|
||||
if (pat_hash == str_hash &&
|
||||
check_if_equal(str , pat , i , i+pat.size()-1 , 0 , pat.size()-1)) {
|
||||
return i;
|
||||
}
|
||||
if (i < str.size()-pat.size()) {
|
||||
str_hash =
|
||||
recalculate_hash(str, i, i+pat.size(), str_hash, pat.size());
|
||||
}
|
||||
}
|
||||
return -1; // return -1 if given pattern not found
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
assert(rabin_karp("helloWorld", "world") == -1);
|
||||
assert(rabin_karp("helloWorld", "World") == 5);
|
||||
assert(rabin_karp("this_is_c++" , "c++") == 8);
|
||||
assert(rabin_karp("happy_coding", "happy") == 0);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user