diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..3ced2b5e --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Abraham Hernandez (abraham@abranhe.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 00000000..178ab926 --- /dev/null +++ b/README.md @@ -0,0 +1,46 @@ +
+ C Plus Plus Logo +
+
+ +
+
+

All ▲lgorithms implemented in C Plus Plus

+ + + + + +
+
+ algorithms.abranhe.com +
+ + +## Contents + +- [Arithmetic Analysis](arithmetic-analysis) +- [File Transfer Protocol](file-transfer-protocol) +- [Greedy Algorithms](greedy-algorithms) +- [Graphs](graphs) +- [Math](math) +- [Neutral Network](neutral-network) +- [Ciphers](ciphers) +- [Data Structures](data-structures) +- [Dynamic Programming](dynamic-programming) +- [Hashes](hashes) +- [Searches](searches) +- [Sorting](sorting) +- [Strings](https://github.com/AllAlgorithms/cpp/tree/master/Strings) +- [Traversals](traversals) + +## License + +This work is licensed under a [MIT License](https://github.com/abranhe/algorithms/blob/master/LICENSE) + +[![MIT IMG][mit-license]]((https://github.com/abranhe/algorithms/blob/master/LICENSE)) + +To the extent possible under law, [Carlos Abraham](https://go.abranhe.com/github) has waived all copyright and related or neighboring rights to this work. + + +[mit-license]: https://cdn.abraham.gq/projects/algorithms/mit-license.png diff --git a/Strings/Rabin_carp_algo.cpp b/Strings/Rabin_carp_algo.cpp new file mode 100644 index 00000000..acd6fd15 --- /dev/null +++ b/Strings/Rabin_carp_algo.cpp @@ -0,0 +1,117 @@ + /* + + * C++ Program to Implement Rabin-Karp Algorithm + + */ + + #include + + #include + + #include + + #include + + using namespace std; + + #define d 256 + + /* + + * search a substring in a string + + */ + + void search(char *pat, char *txt, int q) + + { + + int M = strlen(pat); + + int N = strlen(txt); + + int i, j; + + int p = 0; + + int t = 0; + + int h = 1; + + for (i = 0; i < M - 1; i++) + + h = (h * d) % q; + + for (i = 0; i < M; i++) + + { + + p = (d *p + pat[i]) % q; + + t = (d * t + txt[i]) % q; + + } + + for (i = 0; i <= N - M; i++) + + { + + if (p == t) + + { + + for (j = 0; j < M; j++) + + { + + if (txt[i + j] != pat[j]) + + break; + + } + + if (j == M) + + { + + cout<<"Pattern found at index: "< + + #include + + #include + + using namespace std; + + bool zAlgorithm(string pattern, string target) + + { + + string s = pattern + '$' + target; + + int n = s.length(); + + vector z(n, 0); + + int goal = pattern.length(); + + int r = 0, l = 0, i; + + for (int k = 1; k < n; k++) + + { + + if (k > r) + + { + + for (i = k; i < n && s[i] == s[i - k]; i++); + + if (i > k) + + { + + z[k] = i - k; + + l = k; + + r = i - 1; + + } + + } + + else + + { + + int kt = k - l, b = r - k + 1; + + if (z[kt] > b) + + { + + for (i = r + 1; i < n && s[i] == s[i - k]; i++); + + z[k] = i - k; + + l = k; + + r = i - 1; + + } + + } + + if (z[k] == goal) + + return true; + + } + + return false; + + } + + + + int main() + + { + + string tar = "This is a sample Testcase"; + + string pat = "case"; + + if (zAlgorithm(pat, tar)) + + cout<<"'"< + +using namespace std; + +int count( int S[], int m, int n ) +{ + int i, j, x, y; + + // We need n+1 rows as the table is constructed + // in bottom up manner using the base case 0 + // value case (n = 0) + int table[n+1][m]; + + // Fill the enteries for 0 value case (n = 0) + for (i=0; i= 0)? table[i - S[j]][j]: 0; + // Count of solutions excluding S[j] + y = (j >= 1)? table[i][j-1]: 0; + table[i][j] = x + y; + } + } + return table[n][m-1]; +} + +int main() +{ + int coins[] = {1, 2, 3}; + int m = sizeof(coins)/sizeof(int); + int n = 5; + cout << count(coins, m, n); + return 0; +} diff --git a/dynamic-programming/edit-distance.cpp b/dynamic-programming/edit-distance.cpp new file mode 100644 index 00000000..09190183 --- /dev/null +++ b/dynamic-programming/edit-distance.cpp @@ -0,0 +1,60 @@ + +// A Dynamic Programming based C++ program to find minimum +// number operations to convert str1 to str2 +#include +using namespace std; + +// Utility function to find the minimum of three numbers +int min(int x, int y, int z) +{ + return min(min(x, y), z); +} + +int editDistDP(string str1, string str2, int m, int n) +{ + // Create a table to store results of subproblems + int dp[m+1][n+1]; + + // Fill d[][] in bottom up manner + for (int i=0; i<=m; i++) + { + for (int j=0; j<=n; j++) + { + // If first string is empty, only option is to + // isnert all characters of second string + if (i==0) + dp[i][j] = j; // Min. operations = j + + // If second string is empty, only option is to + // remove all characters of second string + else if (j==0) + dp[i][j] = i; // Min. operations = i + + // If last characters are same, ignore last char + // and recur for remaining string + else if (str1[i-1] == str2[j-1]) + dp[i][j] = dp[i-1][j-1]; + + // If the last character is different, consider all + // possibilities and find the minimum + else + dp[i][j] = 1 + min(dp[i][j-1], // Insert + dp[i-1][j], // Remove + dp[i-1][j-1]); // Replace + } + } + + return dp[m][n]; +} + +// Driver program +int main() +{ + // your code goes here + string str1 = "sunday"; + string str2 = "saturday"; + + cout << editDistDP(str1, str2, str1.length(), str2.length()); + + return 0; +} diff --git a/dynamic-programming/knapsack.cpp b/dynamic-programming/knapsack.cpp new file mode 100644 index 00000000..dc0c188a --- /dev/null +++ b/dynamic-programming/knapsack.cpp @@ -0,0 +1,39 @@ + +// A Dynamic Programming based solution for 0-1 Knapsack problem +#include + +// A utility function that returns maximum of two integers +int max(int a, int b) { return (a > b)? a : b; } + +// Returns the maximum value that can be put in a knapsack of capacity W +int knapSack(int W, int wt[], int val[], int n) +{ + int i, w; + int K[n+1][W+1]; + + // Build table K[][] in bottom up manner + for (i = 0; i <= n; i++) + { + for (w = 0; w <= W; w++) + { + if (i==0 || w==0) + K[i][w] = 0; + else if (wt[i-1] <= w) + K[i][w] = max(val[i-1] + K[i-1][w-wt[i-1]], K[i-1][w]); + else + K[i][w] = K[i-1][w]; + } + } + + return K[n][W]; +} + +int main() +{ + int val[] = {60, 100, 120}; + int wt[] = {10, 20, 30}; + int W = 50; + int n = sizeof(val)/sizeof(val[0]); + cout << knapSack(W, wt, val, n); + return 0; +} diff --git a/dynamic-programming/lcs.cpp b/dynamic-programming/lcs.cpp new file mode 100644 index 00000000..bad7d889 --- /dev/null +++ b/dynamic-programming/lcs.cpp @@ -0,0 +1,52 @@ + +/* Dynamic Programming C/C++ implementation of LCS problem */ +#include + +int max(int a, int b); + +/* Returns length of LCS for X[0..m-1], Y[0..n-1] */ +int lcs( char *X, char *Y, int m, int n ) +{ + int L[m+1][n+1]; + int i, j; + + /* Following steps build L[m+1][n+1] in bottom up fashion. Note + that L[i][j] contains length of LCS of X[0..i-1] and Y[0..j-1] */ + for (i=0; i<=m; i++) + { + for (j=0; j<=n; j++) + { + if (i == 0 || j == 0) + L[i][j] = 0; + + else if (X[i-1] == Y[j-1]) + L[i][j] = L[i-1][j-1] + 1; + + else + L[i][j] = max(L[i-1][j], L[i][j-1]); + } + } + + /* L[m][n] contains length of LCS for X[0..n-1] and Y[0..m-1] */ + return L[m][n]; +} + +/* Utility function to get max of 2 integers */ +int max(int a, int b) +{ + return (a > b)? a : b; +} + +/* Driver program to test above function */ +int main() +{ + char X[] = "AGGTAB"; + char Y[] = "GXTXAYB"; + + int m = strlen(X); + int n = strlen(Y); + + cout << "Length of LCS is " << lcs( X, Y, m, n ) ; + + return 0; +} diff --git a/dynamic-programming/longest_path.cpp b/dynamic-programming/longest_path.cpp new file mode 100644 index 00000000..7d458d73 --- /dev/null +++ b/dynamic-programming/longest_path.cpp @@ -0,0 +1,70 @@ + +#include +#define n 3 +using namespace std; + +// Returns length of the longest path beginning with mat[i][j]. +// This function mainly uses lookup table dp[n][n] +int findLongestFromACell(int i, int j, int mat[n][n], int dp[n][n]) +{ + // Base case + if (i<0 || i>=n || j<0 || j>=n) + return 0; + + // If this subproblem is already solved + if (dp[i][j] != -1) + return dp[i][j]; + + // Since all numbers are unique and in range from 1 to n*n, + // there is atmost one possible direction from any cell + if (j0 && (mat[i][j] +1 == mat[i][j-1])) + return dp[i][j] = 1 + findLongestFromACell(i,j-1,mat,dp); + + if (i>0 && (mat[i][j] +1 == mat[i-1][j])) + return dp[i][j] = 1 + findLongestFromACell(i-1,j,mat,dp); + + if (i +using namespace std; + +int printCountDP(int dist) +{ + int count[dist+1]; + + // Initialize base values. There is one way to cover 0 and 1 + // distances and two ways to cover 2 distance + count[0] = 1, count[1] = 1, count[2] = 2; + + // Fill the count array in bottom up manner + for (int i=3; i<=dist; i++) + count[i] = count[i-1] + count[i-2] + count[i-3]; + + return count[dist]; +} + +// driver program +int main() +{ + int dist = 4; + cout << printCountDP(dist); + return 0; +} diff --git a/graphs/bellman_ford.cpp b/graphs/bellman_ford.cpp new file mode 100644 index 00000000..340cc6a4 --- /dev/null +++ b/graphs/bellman_ford.cpp @@ -0,0 +1,106 @@ +#include + +struct Edge +{ + int src, dest, weight; +}; + +struct Graph +{ + // V-> Number of vertices, E-> Number of edges + int V, E; + // graph is represented as an array of edges. + struct Edge* edge; +}; + +struct Graph* createGraph(int V, int E) +{ + struct Graph* graph = new Graph; + graph->V = V; + graph->E = E; + graph->edge = new Edge[E]; + return graph; +} + +void printArr(int dist[], int n) +{ + printf("Vertex Distance from Source\n"); + for (int i = 0; i < n; ++i) + printf("%d \t\t %d\n", i, dist[i]); +} + +void BellmanFord(struct Graph* graph, int src) +{ + int V = graph->V; + int E = graph->E; + int dist[V]; + + // Step 1: Initialize distances from src to all other vertices + // as INFINITE + for (int i = 0; i < V; i++) + dist[i] = INT_MAX; + dist[src] = 0; + + // Step 2: Relax all edges |V| - 1 times. A simple shortest + // path from src to any other vertex can have at-most |V| - 1 + // edges + for (int i = 1; i <= V-1; i++) + { + for (int j = 0; j < E; j++) + { + int u = graph->edge[j].src; + int v = graph->edge[j].dest; + int weight = graph->edge[j].weight; + if (dist[u] != INT_MAX && dist[u] + weight < dist[v]) + dist[v] = dist[u] + weight; + } + } + + // Step 3: check for negative-weight cycles. The above step + // guarantees shortest distances if graph doesn't contain + // negative weight cycle. If we get a shorter path, then there + // is a cycle. + for (int i = 0; i < E; i++) + { + int u = graph->edge[i].src; + int v = graph->edge[i].dest; + int weight = graph->edge[i].weight; + if (dist[u] != INT_MAX && dist[u] + weight < dist[v]) + printf("Graph contains negative weight cycle"); + } + printArr(dist, V); + return; +} +int main() +{ + /* Sample graph */ + int V = 5; + int E = 8; + struct Graph* graph = createGraph(V, E); + graph->edge[0].src = 0; + graph->edge[0].dest = 1; + graph->edge[0].weight = -1; + graph->edge[1].src = 0; + graph->edge[1].dest = 2; + graph->edge[1].weight = 4; + graph->edge[2].src = 1; + graph->edge[2].dest = 2; + graph->edge[2].weight = 3; + graph->edge[3].src = 1; + graph->edge[3].dest = 3; + graph->edge[3].weight = 2; + graph->edge[4].src = 1; + graph->edge[4].dest = 4; + graph->edge[4].weight = 2; + graph->edge[5].src = 3; + graph->edge[5].dest = 2; + graph->edge[5].weight = 5; + graph->edge[6].src = 3; + graph->edge[6].dest = 1; + graph->edge[6].weight = 1; + graph->edge[7].src = 4; + graph->edge[7].dest = 3; + graph->edge[7].weight = -3; + BellmanFord(graph, 0); + return 0; +} diff --git a/graphs/bfs.cpp b/graphs/bfs.cpp new file mode 100644 index 00000000..a2480464 --- /dev/null +++ b/graphs/bfs.cpp @@ -0,0 +1,87 @@ +#include +#include + +using namespace std; + +class Graph +{ + int V; // No. of vertices + + // Pointer to an array containing adjacency + // lists + list *adj; +public: + Graph(int V); // Constructor + + // function to add an edge to graph + void addEdge(int v, int w); + + // prints BFS traversal from a given source s + void BFS(int s); +}; + +Graph::Graph(int V) +{ + this->V = V; + adj = new list[V]; +} + +void Graph::addEdge(int v, int w) +{ + adj[v].push_back(w); // Add w to v’s list. +} + +void Graph::BFS(int s) +{ + // Mark all the vertices as not visited + bool *visited = new bool[V]; + for(int i = 0; i < V; i++) + visited[i] = false; + + // Create a queue for BFS + list queue; + + // Mark the current node as visited and enqueue it + visited[s] = true; + queue.push_back(s); + + // 'i' will be used to get all adjacent + // vertices of a vertex + list::iterator i; + + while(!queue.empty()) + { + // Dequeue a vertex from queue and print it + s = queue.front(); + cout << s << " "; + queue.pop_front(); + + // Get all adjacent vertices of the dequeued + // vertex s. If a adjacent has not been visited, + // then mark it visited and enqueue it + for (i = adj[s].begin(); i != adj[s].end(); ++i) + { + if (!visited[*i]) + { + visited[*i] = true; + queue.push_back(*i); + } + } + } +} + +int main() +{ + // Sample graph + Graph g(4); + g.addEdge(0, 1); + g.addEdge(0, 2); + g.addEdge(1, 2); + g.addEdge(2, 0); + g.addEdge(2, 3); + g.addEdge(3, 3); + cout << "Following is Breadth First Traversal " + << "(starting from vertex 2) \n"; + g.BFS(2); + return 0; +} diff --git a/graphs/count_diconnected_components.cpp b/graphs/count_diconnected_components.cpp new file mode 100644 index 00000000..0ee61601 --- /dev/null +++ b/graphs/count_diconnected_components.cpp @@ -0,0 +1,69 @@ +#include +#include +using namespace std; + +int count=1; +// Graph class represents a directed graph +// using adjacency list representation +class Graph +{ + int V; + list *adj; + void DFSUtil(int v, bool visited[]); +public: + Graph(int V); + void addEdge(int v, int w); + void DFS(int v); +}; + +Graph::Graph(int V) +{ + this->V = V; + adj = new list[V]; +} + +void Graph::addEdge(int v, int w) +{ + adj[v].push_back(w); // Add w to v’s list. +} + +void Graph::DFSUtil(int v, bool visited[]) +{ + visited[v] = true; + list::iterator i; + for (i = adj[v].begin(); i != adj[v].end(); ++i) + if (!visited[*i]) + DFSUtil(*i, visited); +} +void Graph::DFS(int v) +{ + bool *visited = new bool[V]; + for (int i = 0; i < V; i++) + visited[i] = false; + DFSUtil(v, visited); + for (int i = 0; i < V; i++) + if(visited[i] == false) + { + count++; + DFSUtil(i, visited); + } +} + +int main() +{ + Graph g(9); + g.addEdge(0, 1); + g.addEdge(0, 2); + g.addEdge(1, 2); + g.addEdge(2, 0); + g.addEdge(2, 3); + g.addEdge(3, 3); + g.addEdge(4, 5); + g.addEdge(6, 7); + g.addEdge(6, 8); + + g.DFS(2); + cout << "Number of disconnected components in the given graph is : " < +#include +using namespace std; + +// Graph class represents a directed graph +// using adjacency list representation +class Graph +{ + int V; + list *adj; + void DFSUtil(int v, bool visited[]); +public: + Graph(int V); + void addEdge(int v, int w); + void DFS(int v); +}; + +Graph::Graph(int V) +{ + this->V = V; + adj = new list[V]; +} + +void Graph::addEdge(int v, int w) +{ + adj[v].push_back(w); // Add w to v’s list. +} + +void Graph::DFSUtil(int v, bool visited[]) +{ + visited[v] = true; + cout << v << " "; + list::iterator i; + for (i = adj[v].begin(); i != adj[v].end(); ++i) + if (!visited[*i]) + DFSUtil(*i, visited); +} +void Graph::DFS(int v) +{ + bool *visited = new bool[V]; + for (int i = 0; i < V; i++) + visited[i] = false; + DFSUtil(v, visited); +} + +int main() +{ + Graph g(4); + g.addEdge(0, 1); + g.addEdge(0, 2); + g.addEdge(1, 2); + g.addEdge(2, 0); + g.addEdge(2, 3); + g.addEdge(3, 3); + cout << "Following is Depth First Traversal (starting from vertex 2)\n"; + g.DFS(2); + return 0; +} diff --git a/graphs/dijkstra.cpp b/graphs/dijkstra.cpp new file mode 100644 index 00000000..571850fb --- /dev/null +++ b/graphs/dijkstra.cpp @@ -0,0 +1,78 @@ +#include +#include + +// Number of vertices in the graph +#define V 9 +int minDistance(int dist[], bool sptSet[]) +{ + // Initialize min value + int min = INT_MAX, min_index; + + for (int v = 0; v < V; v++) + if (sptSet[v] == false && dist[v] <= min) + min = dist[v], min_index = v; + + return min_index; +} + +void printSolution(int dist[], int n) +{ + printf("Vertex Distance from Source\n"); + for (int i = 0; i < V; i++) + printf("%d tt %d\n", i, dist[i]); +} + +void dijkstra(int graph[V][V], int src) +{ + int dist[V]; // The output array. dist[i] will hold the shortest + // distance from src to i + + bool sptSet[V]; // sptSet[i] will true if vertex i is included in shortest + // path tree or shortest distance from src to i is finalized + + // Initialize all distances as INFINITE and stpSet[] as false + for (int i = 0; i < V; i++) + dist[i] = INT_MAX, sptSet[i] = false; + + // Distance of source vertex from itself is always 0 + dist[src] = 0; + + // Find shortest path for all vertices + for (int count = 0; count < V-1; count++) + { + // Pick the minimum distance vertex from the set of vertices not + // yet processed. u is always equal to src in the first iteration. + int u = minDistance(dist, sptSet); + + // Mark the picked vertex as processed + sptSet[u] = true; + + // Update dist value of the adjacent vertices of the picked vertex. + for (int v = 0; v < V; v++) + + // Update dist[v] only if is not in sptSet, there is an edge from + // u to v, and total weight of path from src to v through u is + // smaller than current value of dist[v] + if (!sptSet[v] && graph[u][v] && dist[u] != INT_MAX + && dist[u]+graph[u][v] < dist[v]) + dist[v] = dist[u] + graph[u][v]; + } + printSolution(dist, V); +} + +int main() +{ + /* Sample graph */ + int graph[V][V] = {{0, 4, 0, 0, 0, 0, 0, 8, 0}, + {4, 0, 8, 0, 0, 0, 0, 11, 0}, + {0, 8, 0, 7, 0, 4, 0, 0, 2}, + {0, 0, 7, 0, 9, 14, 0, 0, 0}, + {0, 0, 0, 9, 0, 10, 0, 0, 0}, + {0, 0, 4, 14, 10, 0, 2, 0, 0}, + {0, 0, 0, 0, 0, 2, 0, 1, 6}, + {8, 11, 0, 0, 0, 0, 1, 0, 7}, + {0, 0, 2, 0, 0, 0, 6, 7, 0} + }; + dijkstra(graph, 0); + return 0; +} diff --git a/graphs/floyd_warshall.cpp b/graphs/floyd_warshall.cpp new file mode 100644 index 00000000..2c326d10 --- /dev/null +++ b/graphs/floyd_warshall.cpp @@ -0,0 +1,69 @@ +#include + +#define V 4 // Number of vertices in the graph +#define INF 1e7 + +void printSolution(int dist[][V]); +void floydWarshall (int graph[][V]) +{ + int dist[V][V], i, j, k; + /* Initialize the solution matrix same as input graph matrix. Or + we can say the initial values of shortest distances are based + on shortest paths considering no intermediate vertex. */ + for (i = 0; i < V; i++) + for (j = 0; j < V; j++) + dist[i][j] = graph[i][j]; + /* Add all vertices one by one to the set of intermediate vertices. + ---> Before start of an iteration, we have shortest distances between all + pairs of vertices such that the shortest distances consider only the + vertices in set {0, 1, 2, .. k-1} as intermediate vertices. + ----> After the end of an iteration, vertex no. k is added to the set of + intermediate vertices and the set becomes {0, 1, 2, .. k} */ + for (k = 0; k < V; k++) + { + // Pick all vertices as source one by one + for (i = 0; i < V; i++) + { + // Pick all vertices as destination for the + // above picked source + for (j = 0; j < V; j++) + { + // If vertex k is on the shortest path from + // i to j, then update the value of dist[i][j] + if (dist[i][k] + dist[k][j] < dist[i][j]) + dist[i][j] = dist[i][k] + dist[k][j]; + } + } + } + // Print the shortest distance matrix + printSolution(dist); +} + +void printSolution(int dist[][V]) +{ + printf ("The following matrix shows the shortest distances" + " between every pair of vertices \n"); + for (int i = 0; i < V; i++) + { + for (int j = 0; j < V; j++) + { + if (dist[i][j] == INF) + printf("%7s", "INF"); + else + printf ("%7d", dist[i][j]); + } + printf("\n"); + } +} + +int main() +{ + // Sample graph + int graph[V][V] = { {0, 5, INF, 10}, + {INF, 0, 3, INF}, + {INF, INF, 0, 1}, + {INF, INF, INF, 0} + }; + floydWarshall(graph); + return 0; +} diff --git a/graphs/prims_adjacency_list.cpp b/graphs/prims_adjacency_list.cpp new file mode 100644 index 00000000..b12c8137 --- /dev/null +++ b/graphs/prims_adjacency_list.cpp @@ -0,0 +1,100 @@ + +/* The following is an implementation of Prim's algorithm + using adjacency list representation of a graph. The data structure + min heap is used for this. There are, again, two implementations + in this, the min heap code can be written differently in a class, or + the priority_queue present in STL can be used. Here, it's the + latter. + Now, a priority_queue is essentially a max heap, but can be used + as given below to form a min heap. The loop statements execute + v+e times, in addition to log(v) time for adding to priority_queue. + Overall, O(v+e)*O(log(v)) = O((e+v)*log(v)) + e = O(v^2) for dense graphs, because e <= v*(v-1)/2 for any connected graph. + And e = O(v), or, v = O(e) for sparsely connected graphs. + Hence, O((e+v)*log(v)) = O(e*log(v)). + The pop() and top() operations take O(log(v)) and O(1) time + respectively. +*/ + +#include +#define INF INT_MAX + +using namespace std; + +int main(){ + + cout << "Enter number of vertices of the graph" << endl; + int v; + cin >> v; + + vector > adj[v]; + int i, j; //Iterators + + cout << "Enter number of edges of the graph" << endl; + int e; + cin>>e; + + cout << "Enter the vertices and their edge weights in the following format :" << endl; + cout << "Vertex1 Vertex2 Weight" << endl; + cout << "PS : First vertex should be 0." << endl; + + for (i = 0; i < e; i ++){ + int v1,v2,w; + cin >> v1 >> v2 >> w; + adj[v1].push_back(make_pair(w,v2)); + adj[v2].push_back(make_pair(w,v1)); + } + + int mst[v]; + //Array to store MST + int keys[v]; + //Key values of every edge + bool included[v]; + //The corresponding vertex has already been included if true + + for (i = 0; i < v; i ++){ + mst[i] = -1; + keys[i] = INF; + //Set all key values to infinity + included[i] = false; + //None of the vertices have been included yet + } + + int selected = 0; + + priority_queue< pair , vector > , greater< pair > > Q; + //Priority queue as a minHeap + pair p; + //This is used to traverse through the vertices + + mst[0] = 0; + Q.push(make_pair(0,0)); + //To start MST with node 0, the root node + + while(!Q.empty()){ + + p = Q.top(); + selected = p.second; + //Edge with minimum weight is selected + Q.pop(); + + for(int i = 0;i < adj[selected].size(); i++ ){ + int next = adj[selected][i].second; + //This variable stores index of the adjacent vertices to 'selected' + int weight = adj[selected][i].first; + + if (!included[next] && keys[next] > weight){ + keys[next] = weight; + Q.push(adj[selected][i]); + mst[next] = selected; + } + } + } + + cout << "Minimum spanning tree has been generated." << endl; + + for(i = 1; i < v; i++){ + cout<< mst[i] <<" "; + } + return 0; +} diff --git a/math/collatz.cpp b/math/collatz.cpp new file mode 100644 index 00000000..c46b99fb --- /dev/null +++ b/math/collatz.cpp @@ -0,0 +1,25 @@ +/* Collatz sequenge +Author: Pablo Trinidad +*/ + +#include +using namespace std; + +void collatz(int n) { + while (n > 1) { + cout << n << " "; + if (n % 2 == 0) { + n = n / 2; + } else { + n = (3 * n) + 1; + } + } + cout << n << endl; +} +int main() { + int n; + cout << "Enter an integer n to compute the Collatz sequence: "; + cin >> n; + collatz(n); + return 0; +} diff --git a/math/euclids_gcd_algo.cpp b/math/euclids_gcd_algo.cpp new file mode 100644 index 00000000..4ef51686 --- /dev/null +++ b/math/euclids_gcd_algo.cpp @@ -0,0 +1,23 @@ +// C++ program to demonstrate Basic Euclidean Algorithm +// Author Bharat Reddy + +#include +using namespace std; + + +int gcd(int a, int b) +{ + if (a == 0) + return b; + return gcd(b % a, a); +} + +int main() +{ + int a,b; + cout<<"Enter 2 numbers : "; + cin>>a>>b; + int g_c_d = gcd(a,b); + cout<<"GCD is < +*/ + +#include +using namespace std; + +int factorial(int n) { + if (n <= 0) { + return 1; + } else { + return n * factorial(n - 1); + } +} + +int main() { + int n; + cout << "Enter an integer n to compute its factorial: "; + cin >> n; + int r = factorial(n); + cout << n << "! = " << r << endl; + return 0; +} diff --git a/math/gcd_of_array.cpp b/math/gcd_of_array.cpp new file mode 100644 index 00000000..eb83a224 --- /dev/null +++ b/math/gcd_of_array.cpp @@ -0,0 +1,36 @@ +// C++ program to find GCD of an array of integers +//Author Bharat Reddy + +#include +using namespace std; + +int gcd(int a, int b) +{ + if (a == 0) + return b; + return gcd(b % a, a); +} + + +int findGCD(int arr[], int n) +{ + int result = arr[0]; + for (int i = 1; i < n; i++) + result = gcd(arr[i], result); + + return result; +} + +int main() +{ + int n; + cout<<"Enter size of array : "; + cin>>n; + int a[n]; + cout<<"Enter elements of array"<>a[i]; + cout << findGCD(a, n) << endl; + return 0; +} \ No newline at end of file diff --git a/math/lcm_of_array.cpp b/math/lcm_of_array.cpp new file mode 100644 index 00000000..a59439fb --- /dev/null +++ b/math/lcm_of_array.cpp @@ -0,0 +1,42 @@ +// C++ program to find LCM of n elements +// Author Bharat Reddy + +#include +using namespace std; + +typedef long long int ll; + + +int gcd(int a, int b) +{ + if (b == 0) + return a; + return gcd(b, a % b); +} + +// Returns LCM of array elements +ll findlcm(int arr[], int n) +{ + + ll ans = arr[0]; + + for (int i = 1; i < n; i++) + ans = (((arr[i] * ans)) / + (gcd(arr[i], ans))); + + return ans; +} + +int main() +{ + int n; + cout<<"Enter size of array : "; + cin>>n; + int a[n]; + cout<<"Enter elements of array"<>a[i]; + printf("%lld\n", findlcm(a, n)); + return 0; +} \ No newline at end of file diff --git a/math/lucky_numbers.cpp b/math/lucky_numbers.cpp new file mode 100644 index 00000000..351f43f5 --- /dev/null +++ b/math/lucky_numbers.cpp @@ -0,0 +1,37 @@ +// Lucky number implementation +// Carlos Abraham Hernandez +// algorithms.abranhe.com/math/lucky-numbers + +#include +#define bool int + +/* Returns 1 if n is a lucky no. ohterwise returns 0*/ +bool isLucky(int n) +{ + static int counter = 2; + + /*variable next_position is just for readability of + the program we can remove it and use n only */ + int next_position = n; + if(counter > n) + return 1; + if(n%counter == 0) + return 0; + + /*calculate next position of input no*/ + next_position -= next_position/counter; + + counter++; + return isLucky(next_position); +} + +/*Driver function to test above function*/ +int main() +{ + int x = 7; + if( isLucky(x) ) + printf("%d is a lucky number.", x); + else + printf("%d is not a lucky number.", x); + getchar(); +} diff --git a/searches/binary_search.cpp b/searches/binary_search.cpp new file mode 100644 index 00000000..fae0d170 --- /dev/null +++ b/searches/binary_search.cpp @@ -0,0 +1,47 @@ +// Binary Search implemented in C++ +// Carlos Abraham Hernandez +// algorithms.abranhe.com/searches/binary-search +// repl.it/@abranhe/Binary-Search + +#include +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; +} diff --git a/searches/jump_search.cpp b/searches/jump_search.cpp new file mode 100644 index 00000000..203bd78e --- /dev/null +++ b/searches/jump_search.cpp @@ -0,0 +1,62 @@ +// C++ program to implement Jump Search +//Author Bharat Reddy + +#include +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 n,i; + cout<<"Eneter size of array : "; + cin>>n; + cout<<"Enter elements of array"<>a[i]; + sort(a,a+n); + cout<<"Enter key to be searched : "; + int key; + cin>>key; + + // Find the index of 'x' using Jump Search + int index = jumpSearch(a, key, n); + + // Print the index where 'x' is located + cout << "\nNumber " << key << " is at index " << index; + return 0; +} \ No newline at end of file diff --git a/searches/linear_search.cpp b/searches/linear_search.cpp new file mode 100644 index 00000000..61d3ee91 --- /dev/null +++ b/searches/linear_search.cpp @@ -0,0 +1,39 @@ +// Binary Search implemented in C++ +//Author : Bharat Reddy + +#include +using namespace std; + +int linear_search(int a[], int n, int key) +{ + int i; + for(i=0;i>n; + cout<<"Enter elements of array"<>a[i]; + cout<<"Enter key to be searched : "; + int key; + cin>>key; + int res = linear_search(a,n,key); + if(res==-1) + { + cout< arr[j+1]) - swap(&arr[j], &arr[j+1]); + for (size_t i = 0; i < n - 1; i++) + { + // last i elements are already in place + for (size_t j = 0; j < n-i-1; j++) + { + if (arr[j] > arr[j + 1]) + { + swap(&arr[j], &arr[j + 1]); + } + } + } } -// Function to print elements -void printArray(int arr[], int size) -{ - int i; - for (i=0; i < size; i++) - printf("%d ", arr[i]); - printf("\n"); -} +// A utility function to print an array of size n +void print_array(int arr[], int n) +{ + for (size_t i = 0; i < n; i++) + { + std::cout << arr[i] << " "; + } + std::cout << std::endl; +} -// test int main() { int arr[] = {46, 24, 33, 10, 2, 81, 50}; int n = sizeof(arr)/sizeof(arr[0]); - printf("Unsorted array: \n"); - printArray(arr, n); - bubbleSort(arr, n); - printf("Sorted array: \n"); - printArray(arr, n); - return 0; + std::cout << "Unsorted array:" << std::endl; + print_array(arr, n); + bubble_sort(arr, n); + std::cout << "Sorted array:" << std::endl; + print_array(arr, n); + return 0; } diff --git a/sorting/insertion_sort.cpp b/sorting/insertion_sort.cpp new file mode 100644 index 00000000..b6cec71d --- /dev/null +++ b/sorting/insertion_sort.cpp @@ -0,0 +1,53 @@ +// C++ implementation of insertion sort +// +// Author: Andres Langberg + + +#include + +/* Function to sort an array using insertion sort*/ +void insertion_sort(int arr[], int n) +{ + int key; + size_t j; + for (size_t i = 1; i < n; i++) + { + key = arr[i]; + j = i - 1; + + /* Move elements of arr[0..i-1], that are + greater than key, to one position ahead + of their current position */ + while (j >= 0 && arr[j] > key) + { + arr[j + 1] = arr[j]; + j--; + } + arr[j + 1] = key; + } +} + +// A utility function to print an array of size n +void print_array(int arr[], int n) +{ + for (size_t i = 0; i < n; i++) + { + std::cout << arr[i] << " "; + } + std::cout << std::endl; +} + + + +/* Driver program to test insertion sort */ +int main() +{ + int arr[] = {12, 11, 13, 5, 6}; + size_t n = sizeof(arr) / sizeof(arr[0]); + std::cout << "Unsorted array:" << std::endl; + print_array(arr, n); + insertion_sort(arr, n); + std::cout << "Sorted array:" << std::endl; + print_array(arr, n); + return 0; +} diff --git a/sorting/merge_sort.cpp b/sorting/merge_sort.cpp index 4c86dd3c..3865c2b9 100644 --- a/sorting/merge_sort.cpp +++ b/sorting/merge_sort.cpp @@ -5,8 +5,7 @@ // abraham@abranhe.com //**************************************** -#include -#include +#include // Merge the two half into a sorted data. void merge(int arr[], int l, int m, int r) @@ -16,8 +15,8 @@ void merge(int arr[], int l, int m, int r) int n2 = r - m; /* create temp arrays */ - int L[n1], R[n2]; - + int* L = new int[n1]; + int* R = new int[n2]; /* Copy data to temp arrays L[] and R[] */ for (i = 0; i < n1; i++) L[i] = arr[l + i]; @@ -60,48 +59,48 @@ void merge(int arr[], int l, int m, int r) j++; k++; } + delete[] L; + delete[] R; } /* l is for left index and r is right index of the sub-array of arr to be sorted */ -void mergeSort(int arr[], int l, int r) +void merge_sort(int arr[], int l, int r) { if (l < r) { // Same as (l+r)/2, but avoids overflow for // large l and h - int m = l+(r-l)/2; + int m = l + (r - l) / 2; // Sort first and second halves - mergeSort(arr, l, m); - mergeSort(arr, m+1, r); + merge_sort(arr, l, m); + merge_sort(arr, m + 1, r); merge(arr, l, m, r); } } /* UTILITY FUNCTIONS */ -/* Function to print an array */ -void printArray(int A[], int size) -{ - int i; - for (i=0; i < size; i++) - printf("%d ", A[i]); - printf("\n"); -} +// A utility function to print an array of size n +void print_array(int arr[], int n) +{ + for (size_t i = 0; i < n; i++) + { + std::cout << arr[i] << " "; + } + std::cout << std::endl; +} /* Driver program to test above functions */ int main() { int arr[] = {12, 11, 13, 5, 6, 7}; int arr_size = sizeof(arr)/sizeof(arr[0]); - - printf("Given array is \n"); - printArray(arr, arr_size); - - mergeSort(arr, 0, arr_size - 1); - - printf("\nSorted array is \n"); - printArray(arr, arr_size); + std::cout << "Unsorted array:" << std::endl; + print_array(arr, arr_size); + merge_sort(arr, 0, arr_size - 1); + std::cout << "Sorted array:" << std::endl; + print_array(arr, arr_size); return 0; } diff --git a/sorting/quick_sort.cpp b/sorting/quick_sort.cpp new file mode 100644 index 00000000..91407403 --- /dev/null +++ b/sorting/quick_sort.cpp @@ -0,0 +1,56 @@ +#include +#include + +void quick_sort(std::vector&, size_t, size_t); +int partition(std::vector&, size_t, size_t); + +void quick_sort(std::vector& arr, size_t start, size_t end) +{ + if(start < end) + { + int pivot = partition(arr, start, end); + quick_sort(arr, start, pivot); + quick_sort(arr, pivot + 1, end); + } +} + + +int partition(std::vector& arr, size_t start, size_t end) +{ + int x = arr[start]; + int i = start; + for(size_t j = start + 1; j < end; j++) + { + if(arr[j]<=x) + { + i=i+1; + std::swap(arr[i], arr[j]); + } + } + std::swap(arr[i], arr[start]); + return i; +} + + +void print_vector(std::vector& arr) +{ + for (size_t i = 0; i < arr.size(); i++) + { + std::cout << arr[i] << " "; + } + std::cout << std::endl; +} + + +int main() +{ + std::vector arr = {10,9,8,7,6,5,4,3,2,1}; + int start = 0; + int end = arr.size(); + std::cout << "Unsorted array:" << std::endl; + print_vector(arr); + quick_sort(arr, start, end); + std::cout << "Sorted array:" << std::endl; + print_vector(arr); +} + diff --git a/sorting/selection_sort.cpp b/sorting/selection_sort.cpp new file mode 100644 index 00000000..0ba110d0 --- /dev/null +++ b/sorting/selection_sort.cpp @@ -0,0 +1,49 @@ +// C++ implementation of selection sort +// +// Author: Rituparno Biswas + +#include + +// Swap elements +void swap(int *x, int *y) +{ + int temp = *x; + *x = *y; + *y = temp; +} + +// Implement selection sort +void selectionSort(int arr[], int n) +{ + int i, j, min_id; + for (i = 0; i < n-1; i++) + { + min_id=i; + for (j = i+1; j < n; j++) + if (arr[min_id] > arr[j]) + min_id=j; + swap(&arr[i], &arr[min_id]); + } +} + +// Function to print elements +void printArray(int arr[], int size) +{ + int i; + for (i=0; i < size; i++) + printf("%d ", arr[i]); + printf("\n"); +} + +// test +int main() +{ + int arr[] = {46, 24, 33, 10, 2, 81, 50}; + int n = sizeof(arr)/sizeof(arr[0]); + printf("Unsorted array: \n"); + printArray(arr, n); + selectionSort(arr, n); + printf("Sorted array: \n"); + printArray(arr, n); + return 0; +} diff --git a/sorting/shaker_sort.cpp b/sorting/shaker_sort.cpp new file mode 100644 index 00000000..f65f3d8e --- /dev/null +++ b/sorting/shaker_sort.cpp @@ -0,0 +1,61 @@ +#include + +using namespace std; + +// A function to swap values using call by reference. +void swap(int *a, int *b) +{ + int temp; + temp = *a; + *a = *b; + *b = temp; +} + +// A function implementing shaker sort. +void ShakerSort(int a[], int n) +{ + int i, j, k; + for(i = 0; i < n;) + { + // First phase for ascending highest value to the highest unsorted index. + for(j = i+1; j < n; j++) + { + if(a[j] < a[j-1]) + swap(&a[j], &a[j-1]); + } + // Decrementing highest index. + n--; + + // Second phase for descending lowest value to the lowest unsorted index. + for(k = n-1; k > i; k--) + { + if(a[k] < a[k-1]) + swap(&a[k], &a[k-1]); + } + // Incrementing lowest index. + i++; + } +} + +int main() +{ + int n, i; + cout<<"\nEnter the number of data element to be sorted: "; + cin>>n; + + int arr[n]; + for(i = 0; i < n; i++) + { + cout<<"Enter element "<>arr[i]; + } + + ShakerSort(arr, n); + + // Printing the sorted data. + cout<<"\nSorted Data "; + for (i = 0; i < n; i++) + cout<<"->"< + +using namespace std; + +// A function implementing stooge sort. +void StoogeSort(int a[],int start, int end) +{ + int temp; + // Further breaking the array if the Subpart's length is more than 2. + if(end-start+1 > 2) + { + temp = (end-start+1)/3; + StoogeSort(a, start, end-temp); + StoogeSort(a, start+temp, end); + StoogeSort(a, start, end-temp); + } + + // swapping the element at start and end. + if(a[end] < a[start]) + { + temp = a[start]; + a[start] = a[end]; + a[end] = temp; + } +} + +int main() +{ + int n, i; + cout<<"\nEnter the number of data element to be sorted: "; + cin>>n; + + int arr[n]; + for(i = 0; i < n; i++) + { + cout<<"Enter element "<>arr[i]; + } + + StoogeSort(arr, 0, n-1); + + // Printing the sorted data. + cout<<"\nSorted Data "; + for (i = 0; i < n; i++) + cout<<"->"< +#include + +/* Function prototype for string a given string using + quick sort */ +void quickSort(char *arr, int si, int ei); + +/* function to check whether two strings are anagram of + each other */ +bool areAnagram(char *str1, char *str2) +{ + // Get lenghts of both strings + int n1 = strlen(str1); + int n2 = strlen(str2); + + // If length of both strings is not same, then they + // cannot be anagram + if (n1 != n2) + return false; + + // Sort both strings + quickSort(str1, 0, n1 - 1); + quickSort(str2, 0, n2 - 1); + + // Compare sorted strings + for (int i = 0; i < n1; i++) + if (str1[i] != str2[i]) + return false; + + return true; +} + +// Following functions (exchange and partition are needed +// for quickSort) +void exchange(char *a, char *b) +{ + char temp; + temp = *a; + *a = *b; + *b = temp; +} + +int partition(char A[], int si, int ei) +{ + char x = A[ei]; + int i = (si - 1); + int j; + + for (j = si; j <= ei - 1; j++) + { + if(A[j] <= x) + { + i++; + exchange(&A[i], &A[j]); + } + } + exchange (&A[i + 1], &A[ei]); + return (i + 1); +} + +/* Implementation of Quick Sort +A[] --> Array to be sorted +si --> Starting index +ei --> Ending index +*/ +void quickSort(char A[], int si, int ei) +{ + int pi; /* Partitioning index */ + if(si < ei) + { + pi = partition(A, si, ei); + quickSort(A, si, pi - 1); + quickSort(A, pi + 1, ei); + } +} + +/* Driver program to test to print printDups*/ +int main() +{ + char str1[] = ""; //String 1 + char str2[] = ""; //String 2 + if (areAnagram(str1, str2)) + printf("The two strings are anagram of each other"); + else + printf("The two strings are not anagram of each other"); + + return 0; +} \ No newline at end of file diff --git a/strings/lexicographic-ranking.cpp b/strings/lexicographic-ranking.cpp new file mode 100644 index 00000000..125a2c59 --- /dev/null +++ b/strings/lexicographic-ranking.cpp @@ -0,0 +1,53 @@ +#include +#include + +// A utility function to find factorial of n +int fact(int n) +{ + return (n <= 1)? 1 :n * fact(n-1); +} + +// A utility function to count smaller characters on right +// of arr[low] +int findSmallerInRight(char* str, int low, int high) +{ + int countRight = 0, i; + + for (i = low+1; i <= high; ++i) + if (str[i] < str[low]) + ++countRight; + + return countRight; +} + +// A function to find rank of a string in all permutations +// of characters +int findRank (char* str) +{ + int len = strlen(str); + int mul = fact(len); + int rank = 1; + int countRight; + + int i; + for (i = 0; i < len; ++i) + { + mul /= len - i; + + // count number of chars smaller than str[i] + // fron str[i+1] to str[len-1] + countRight = findSmallerInRight(str, i, len-1); + + rank += countRight * mul ; + } + + return rank; +} + +// Driver program to test above function +int main() +{ + char str[] = ""; //Enter string here + printf ("%d", findRank(str)); + return 0; +} \ No newline at end of file diff --git a/strings/longest-palindrome-subset.cpp b/strings/longest-palindrome-subset.cpp new file mode 100644 index 00000000..78777e1c --- /dev/null +++ b/strings/longest-palindrome-subset.cpp @@ -0,0 +1,84 @@ +// A dynamic programming solution for longest palindr. +// This code is adopted from following link +// http://www.leetcode.com/2011/11/longest-palindromic-substring-part-i.html + +#include +#include + +// A utility function to print a substring str[low..high] +void printSubStr( char* str, int low, int high ) +{ + for( int i = low; i <= high; ++i ) + printf("%c", str[i]); +} + +// This function prints the longest palindrome substring +// of str[]. +// It also returns the length of the longest palindrome +int longestPalSubstr( char *str ) +{ + int n = strlen( str ); // get length of input string + + // table[i][j] will be false if substring str[i..j] + // is not palindrome. + // Else table[i][j] will be true + bool table[n][n]; + memset(table, 0, sizeof(table)); + + // All substrings of length 1 are palindromes + int maxLength = 1; + for (int i = 0; i < n; ++i) + table[i][i] = true; + + // check for sub-string of length 2. + int start = 0; + for (int i = 0; i < n-1; ++i) + { + if (str[i] == str[i+1]) + { + table[i][i+1] = true; + start = i; + maxLength = 2; + } + } + + // Check for lengths greater than 2. k is length + // of substring + for (int k = 3; k <= n; ++k) + { + // Fix the starting index + for (int i = 0; i < n-k+1 ; ++i) + { + // Get the ending index of substring from + // starting index i and length k + int j = i + k - 1; + + // checking for sub-string from ith index to + // jth index iff str[i+1] to str[j-1] is a + // palindrome + if (table[i+1][j-1] && str[i] == str[j]) + { + table[i][j] = true; + + if (k > maxLength) + { + start = i; + maxLength = k; + } + } + } + } + + printf("Longest palindrome substring is: "); + printSubStr( str, start, start + maxLength - 1 ); + + return maxLength; // return length of LPS +} + +// Driver program to test above functions +int main() +{ + char str[] = ""; //Enter string here + printf("\nLength is: %d\n", longestPalSubstr( str ) ); + return 0; +} \ No newline at end of file diff --git a/strings/naive-search.cpp b/strings/naive-search.cpp new file mode 100644 index 00000000..0f00e1fe --- /dev/null +++ b/strings/naive-search.cpp @@ -0,0 +1,43 @@ +/* C program for A modified Naive Pattern Searching + algorithm that is optimized for the cases when all + characters of pattern are different */ +#include +#include + +/* A modified Naive Pettern Searching algorithn that is optimized + for the cases when all characters of pattern are different */ +void search(char pat[], char txt[]) +{ + int M = strlen(pat); + int N = strlen(txt); + int i = 0; + + while (i <= N - M) + { + int j; + + /* For current index i, check for pattern match */ + for (j = 0; j < M; j++) + if (txt[i+j] != pat[j]) + break; + + if (j == M) // if pat[0...M-1] = txt[i, i+1, ...i+M-1] + { + printf("Pattern found at index %d \n", i); + i = i + M; + } + else if (j == 0) + i = i + 1; + else + i = i + j; // slide the pattern by j + } +} + +/* Driver program to test above function */ +int main() +{ + char txt[] = ""; //Enter the entire string here + char pat[] = ""; //Enter the string to be searched here + search(pat, txt); + return 0; +} \ No newline at end of file diff --git a/strings/permutations-of-string.cpp b/strings/permutations-of-string.cpp new file mode 100644 index 00000000..b49aa044 --- /dev/null +++ b/strings/permutations-of-string.cpp @@ -0,0 +1,71 @@ +# C program to print all permutations with repetition +# of characters +#include +#include +#include + +/* Following function is used by the library qsort() function + to sort an array of chars */ +int compare (const void * a, const void * b); + +/* The main function that recursively prints all repeated + permutations of the given string. It uses data[] to store all + permutations one by one */ +void allLexicographicRecur (char *str, char* data, int last, int index) +{ + int i, len = strlen(str); + + // One by one fix all characters at the given index and recur for + // the/ subsequent indexes + for ( i=0; i +# include +# define NO_OF_CHARS 256 + +/* Fills count array with frequency of characters */ +void fillCharCounts(char *str, int *count) +{ + int i; + for (i = 0; *(str+i); i++) + count[*(str+i)]++; +} + +/* Print duplicates present in the passed string */ +void printDups(char *str) +{ + // Create an array of size 256 and fill count of every character in it + int *count = (int *)calloc(NO_OF_CHARS, sizeof(int)); + fillCharCounts(str, count); + + // Print characters having count more than 0 + int i; + for (i = 0; i < NO_OF_CHARS; i++) + if(count[i] > 1) + printf("%c, count = %d \n", i, count[i]); + + free(count); +} + +/* Driver program to test to pront printDups*/ +int main() +{ + char str[] = ""; //Enter string here + printDups(str); + getchar(); + return 0; +} \ No newline at end of file diff --git a/strings/rabin-karp.cpp b/strings/rabin-karp.cpp new file mode 100644 index 00000000..e0c36ef6 --- /dev/null +++ b/strings/rabin-karp.cpp @@ -0,0 +1,77 @@ +/* Following program is a C implementation of Rabin Karp +Algorithm given in the CLRS book */ +#include +#include + +// d is the number of characters in the input alphabet +#define d 256 + +/* pat -> pattern + txt -> text + q -> A prime number +*/ +void search(char pat[], char txt[], int q) +{ + int M = strlen(pat); + int N = strlen(txt); + int i, j; + int p = 0; // hash value for pattern + int t = 0; // hash value for txt + int h = 1; + + // The value of h would be "pow(d, M-1)%q" + for (i = 0; i < M-1; i++) + h = (h*d)%q; + + // Calculate the hash value of pattern and first + // window of text + for (i = 0; i < M; i++) + { + p = (d*p + pat[i])%q; + t = (d*t + txt[i])%q; + } + + // Slide the pattern over text one by one + for (i = 0; i <= N - M; i++) + { + + // Check the hash values of current window of text + // and pattern. If the hash values match then only + // check for characters on by one + if ( p == t ) + { + /* Check for characters one by one */ + for (j = 0; j < M; j++) + { + if (txt[i+j] != pat[j]) + break; + } + + // if p == t and pat[0...M-1] = txt[i, i+1, ...i+M-1] + if (j == M) + printf("Pattern found at index %d \n", i); + } + + // Calculate hash value for next window of text: Remove + // leading digit, add trailing digit + if ( i < N-M ) + { + t = (d*(t - txt[i]*h) + txt[i+M])%q; + + // We might get negative value of t, converting it + // to positive + if (t < 0) + t = (t + q); + } + } +} + +/* Driver program to test above function */ +int main() +{ + char txt[] = ""; //Enter the entire text here + char pat[] = ""; //Enter the string to be searched here + int q = 101; // A prime number + search(pat, txt, q); + return 0; +} \ No newline at end of file diff --git a/strings/remove-adjacent-duplicates.cpp b/strings/remove-adjacent-duplicates.cpp new file mode 100644 index 00000000..766e5568 --- /dev/null +++ b/strings/remove-adjacent-duplicates.cpp @@ -0,0 +1,65 @@ +// C/C++ program to remove all adjacent duplicates from a string +#include +#include +using namespace std; + +// Recursively removes adjacent duplicates from str and returns +// new string. las_removed is a pointer to last_removed character +char* removeUtil(char *str, char *last_removed) +{ + // If length of string is 1 or 0 + if (str[0] == '\0' || str[1] == '\0') + return str; + + // Remove leftmost same characters and recur for remaining + // string + if (str[0] == str[1]) + { + *last_removed = str[0]; + while (str[1] && str[0] == str[1]) + str++; + str++; + return removeUtil(str, last_removed); + } + + // At this point, the first character is definiotely different + // from its adjacent. Ignore first character and recursively + // remove characters from remaining string + char* rem_str = removeUtil(str+1, last_removed); + + // Check if the first character of the rem_string matches with + // the first character of the original string + if (rem_str[0] && rem_str[0] == str[0]) + { + *last_removed = str[0]; + return (rem_str+1); // Remove first character + } + + // If remaining string becomes empty and last removed character + // is same as first character of original string. This is needed + // for a string like "acbbcddc" + if (rem_str[0] == '\0' && *last_removed == str[0]) + return rem_str; + + // If the two first characters of str and rem_str don't match, + // append first character of str before the first character of + // rem_str. + rem_str--; + rem_str[0] = str[0]; + return rem_str; +} + +char *remove(char *str) +{ + char last_removed = '\0'; + return removeUtil(str, &last_removed); +} + +// Driver program to test above functions +int main() +{ + char str1[] = ""; //Enter string + cout << remove(str1) << endl; + + return 0; +} \ No newline at end of file diff --git a/strings/remove-duplicates-O(n2).cpp b/strings/remove-duplicates-O(n2).cpp new file mode 100644 index 00000000..5e798f56 --- /dev/null +++ b/strings/remove-duplicates-O(n2).cpp @@ -0,0 +1,37 @@ +// CPP program to remove duplicate character +// from character array and print in sorted +// order +#include +using namespace std; + +char *removeDuplicate(char str[], int n) +{ + // Used as index in the modified string + int index = 0; + + // Traverse through all characters + for (int i=0; i +using namespace std; + +char *removeDuplicate(char str[], int n) +{ + // create a set using string characters + // excluding '\0' + sets (str, str+n-1); + + // print content of the set + int i = 0; + for (auto x : s) + str[i++] = x; + str[i] = '\0'; + + return str; +} + +// Driver code +int main() +{ + char str[]= ""; //Enter string here + int n = sizeof(str) / sizeof(str[0]); + cout << removeDuplicate(str, n); + return 0; +} \ No newline at end of file diff --git a/strings/reverse-string.cpp b/strings/reverse-string.cpp new file mode 100644 index 00000000..fc1f725f --- /dev/null +++ b/strings/reverse-string.cpp @@ -0,0 +1,51 @@ +#include + +/* function prototype for utility function to + reverse a string from begin to end */ +void reverse(char* begin, char* end); + +/*Function to reverse words*/ +void reverseWords(char* s) +{ + char* word_begin = s; + char* temp = s; /* temp is for word boundry */ + + /*STEP 1 of the above algorithm */ + while (*temp) { + temp++; + if (*temp == '\0') { + reverse(word_begin, temp - 1); + } + else if (*temp == ' ') { + reverse(word_begin, temp - 1); + word_begin = temp + 1; + } + } /* End of while */ + + /*STEP 2 of the above algorithm */ + reverse(s, temp - 1); +} + +/* UTILITY FUNCTIONS */ +/*Function to reverse any sequence starting with pointer + begin and ending with pointer end */ +void reverse(char* begin, char* end) +{ + char temp; + while (begin < end) { + temp = *begin; + *begin++ = *end; + *end-- = temp; + } +} + +/* Driver function to test above functions */ +int main() +{ + char s[] = ""; //Enter string here + char* temp = s; + reverseWords(s); + printf("%s", s); + getchar(); + return 0; +} \ No newline at end of file