Merge pull request #1 from TheAlgorithms/master

updating the fork
This commit is contained in:
Ayaan Khan
2020-05-27 15:39:54 +05:30
committed by GitHub
26 changed files with 1503 additions and 174 deletions

1
.gitignore vendored
View File

@@ -30,5 +30,6 @@
# Executables
*.exe
a.out
*.out
*.app

View File

@@ -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
}

View File

@@ -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

View File

@@ -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)

View 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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View 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;
}

View 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;
}

View 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;
}

View 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
View 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;
}

View 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
View 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);
}

View 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
View 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;
}

View File

@@ -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

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View File

@@ -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
View 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
View 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
View 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
View 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;
}