Skip to content

Commit f34f93e

Browse files
Swastyygithub-actionsPanquesito7
authored
feat: Add the Subarray Sum implementation (TheAlgorithms#1527)
* Create subarray_sum.cpp * updating DIRECTORY.md * clang-format and clang-tidy fixes for 0a293ec * Update backtracking/subarray_sum.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * clang-format and clang-tidy fixes for f37f7b7 * Update backtracking/subarray_sum.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update backtracking/subarray_sum.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update subarray_sum.cpp * clang-format and clang-tidy fixes for 9b0b5f8 * Update backtracking/subarray_sum.cpp * Update backtracking/subarray_sum.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update backtracking/subarray_sum.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update backtracking/subarray_sum.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * clang-format and clang-tidy fixes for 047366a * Update subarray_sum.cpp * clang-format and clang-tidy fixes for 512b188 * Update backtracking/subarray_sum.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update backtracking/subarray_sum.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update backtracking/subarray_sum.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update backtracking/subarray_sum.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * fix: Apply suggestions from code review * docs: Apply suggestions from code review * clang-format and clang-tidy fixes for e697904 Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Co-authored-by: David Leal <halfpacho@gmail.com>
1 parent 0e0ba5f commit f34f93e

File tree

5 files changed

+540
-353
lines changed

5 files changed

+540
-353
lines changed

DIRECTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* [N Queens All Solution Optimised](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/n_queens_all_solution_optimised.cpp)
99
* [Nqueen Print All Solutions](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/nqueen_print_all_solutions.cpp)
1010
* [Rat Maze](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/rat_maze.cpp)
11+
* [Subarray Sum](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/subarray_sum.cpp)
1112
* [Subset Sum](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/subset_sum.cpp)
1213
* [Sudoku Solve](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/sudoku_solve.cpp)
1314

backtracking/graph_coloring.cpp

Lines changed: 70 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,97 @@
11
/**
22
* @file
33
* @brief prints the assigned colors
4-
* using [Graph Coloring](https://en.wikipedia.org/wiki/Graph_coloring) algorithm
4+
* using [Graph Coloring](https://en.wikipedia.org/wiki/Graph_coloring)
5+
* algorithm
56
*
67
* @details
7-
* In graph theory, graph coloring is a special case of graph labeling;
8-
* it is an assignment of labels traditionally called "colors" to elements of a graph subject to certain constraints.
9-
* In its simplest form, it is a way of coloring the vertices of a graph such that no two adjacent vertices are of the same color;
10-
* this is called a vertex coloring. Similarly, an edge coloring assigns
11-
* a color to each edge so that no two adjacent edges are of the same color,
12-
* and a face coloring of a planar graph assigns a color to each face or
8+
* In graph theory, graph coloring is a special case of graph labeling;
9+
* it is an assignment of labels traditionally called "colors" to elements of a
10+
* graph subject to certain constraints. In its simplest form, it is a way of
11+
* coloring the vertices of a graph such that no two adjacent vertices are of
12+
* the same color; this is called a vertex coloring. Similarly, an edge coloring
13+
* assigns a color to each edge so that no two adjacent edges are of the same
14+
* color, and a face coloring of a planar graph assigns a color to each face or
1315
* region so that no two faces that share a boundary have the same color.
1416
*
1517
* @author [Anup Kumar Panwar](https://github.com/AnupKumarPanwar)
1618
* @author [David Leal](https://github.com/Panquesito7)
1719
*/
18-
#include <iostream>
1920
#include <array>
21+
#include <iostream>
2022
#include <vector>
2123

2224
/**
2325
* @namespace
2426
* @brief Backtracking algorithms
2527
*/
2628
namespace backtracking {
27-
/** A utility function to print solution
28-
* @tparam V number of vertices in the graph
29-
* @param color array of colors assigned to the nodes
30-
*/
31-
template <size_t V>
32-
void printSolution(const std::array <int, V>& color) {
33-
std::cout << "Following are the assigned colors" << std::endl;
34-
for (auto &col : color) {
35-
std::cout << col;
36-
}
37-
std::cout << std::endl;
29+
/** A utility function to print solution
30+
* @tparam V number of vertices in the graph
31+
* @param color array of colors assigned to the nodes
32+
*/
33+
template <size_t V>
34+
void printSolution(const std::array<int, V>& color) {
35+
std::cout << "Following are the assigned colors" << std::endl;
36+
for (auto& col : color) {
37+
std::cout << col;
3838
}
39+
std::cout << std::endl;
40+
}
3941

40-
/** A utility function to check if the current color assignment is safe for
41-
* vertex v
42-
* @tparam V number of vertices in the graph
43-
* @param v index of graph vertex to check
44-
* @param graph matrix of graph nonnectivity
45-
* @param color vector of colors assigned to the graph nodes/vertices
46-
* @param c color value to check for the node `v`
47-
* @returns `true` if the color is safe to be assigned to the node
48-
* @returns `false` if the color is not safe to be assigned to the node
49-
*/
50-
template <size_t V>
51-
bool isSafe(int v, const std::array<std::array <int, V>, V>& graph, const std::array <int, V>& color, int c) {
52-
for (int i = 0; i < V; i++) {
53-
if (graph[v][i] && c == color[i]) {
54-
return false;
55-
}
42+
/** A utility function to check if the current color assignment is safe for
43+
* vertex v
44+
* @tparam V number of vertices in the graph
45+
* @param v index of graph vertex to check
46+
* @param graph matrix of graph nonnectivity
47+
* @param color vector of colors assigned to the graph nodes/vertices
48+
* @param c color value to check for the node `v`
49+
* @returns `true` if the color is safe to be assigned to the node
50+
* @returns `false` if the color is not safe to be assigned to the node
51+
*/
52+
template <size_t V>
53+
bool isSafe(int v, const std::array<std::array<int, V>, V>& graph,
54+
const std::array<int, V>& color, int c) {
55+
for (int i = 0; i < V; i++) {
56+
if (graph[v][i] && c == color[i]) {
57+
return false;
5658
}
57-
return true;
5859
}
60+
return true;
61+
}
5962

60-
/** A recursive utility function to solve m coloring problem
61-
* @tparam V number of vertices in the graph
62-
* @param graph matrix of graph nonnectivity
63-
* @param m number of colors
64-
* @param [in,out] color description // used in,out to notify in documentation
65-
* that this parameter gets modified by the function
66-
* @param v index of graph vertex to check
67-
*/
68-
template <size_t V>
69-
void graphColoring(const std::array<std::array <int, V>, V>& graph, int m, std::array <int, V> color, int v) {
70-
// base case:
71-
// If all vertices are assigned a color then return true
72-
if (v == V) {
73-
backtracking::printSolution<V>(color);
74-
return;
75-
}
63+
/** A recursive utility function to solve m coloring problem
64+
* @tparam V number of vertices in the graph
65+
* @param graph matrix of graph nonnectivity
66+
* @param m number of colors
67+
* @param [in,out] color description // used in,out to notify in documentation
68+
* that this parameter gets modified by the function
69+
* @param v index of graph vertex to check
70+
*/
71+
template <size_t V>
72+
void graphColoring(const std::array<std::array<int, V>, V>& graph, int m,
73+
std::array<int, V> color, int v) {
74+
// base case:
75+
// If all vertices are assigned a color then return true
76+
if (v == V) {
77+
backtracking::printSolution<V>(color);
78+
return;
79+
}
7680

77-
// Consider this vertex v and try different colors
78-
for (int c = 1; c <= m; c++) {
79-
// Check if assignment of color c to v is fine
80-
if (backtracking::isSafe<V>(v, graph, color, c)) {
81-
color[v] = c;
81+
// Consider this vertex v and try different colors
82+
for (int c = 1; c <= m; c++) {
83+
// Check if assignment of color c to v is fine
84+
if (backtracking::isSafe<V>(v, graph, color, c)) {
85+
color[v] = c;
8286

83-
// recur to assign colors to rest of the vertices
84-
backtracking::graphColoring<V>(graph, m, color, v + 1);
87+
// recur to assign colors to rest of the vertices
88+
backtracking::graphColoring<V>(graph, m, color, v + 1);
8589

86-
// If assigning color c doesn't lead to a solution then remove it
87-
color[v] = 0;
88-
}
90+
// If assigning color c doesn't lead to a solution then remove it
91+
color[v] = 0;
8992
}
9093
}
94+
}
9195
} // namespace backtracking
9296

9397
/**
@@ -102,15 +106,12 @@ int main() {
102106
// (0)---(1)
103107

104108
const int V = 4; // number of vertices in the graph
105-
std::array <std::array <int, V>, V> graph = {
106-
std::array <int, V>({0, 1, 1, 1}),
107-
std::array <int, V>({1, 0, 1, 0}),
108-
std::array <int, V>({1, 1, 0, 1}),
109-
std::array <int, V>({1, 0, 1, 0})
110-
};
109+
std::array<std::array<int, V>, V> graph = {
110+
std::array<int, V>({0, 1, 1, 1}), std::array<int, V>({1, 0, 1, 0}),
111+
std::array<int, V>({1, 1, 0, 1}), std::array<int, V>({1, 0, 1, 0})};
111112

112113
int m = 3; // Number of colors
113-
std::array <int, V> color{};
114+
std::array<int, V> color{};
114115

115116
backtracking::graphColoring<V>(graph, m, color, 0);
116117
return 0;

backtracking/subarray_sum.cpp

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/**
2+
* @file
3+
* @brief [Subset-sum](https://en.wikipedia.org/wiki/Subset_sum_problem) (only
4+
* continuous subsets) problem
5+
* @details We are given an array and a sum value. The algorithms find all
6+
* the subarrays of that array with sum equal to the given sum and return such
7+
* subarrays count. This approach will have \f$O(n)\f$ time complexity and
8+
* \f$O(n)\f$ space complexity. NOTE: In this problem, we are only referring to
9+
* the continuous subsets as subarrays everywhere. Subarrays can be created
10+
* using deletion operation at the end of the front of an array only. The parent
11+
* array is also counted in subarrays having 0 number of deletion operations.
12+
*
13+
* @author [Swastika Gupta](https://github.com/Swastyy)
14+
*/
15+
16+
#include <cassert> /// for assert
17+
#include <iostream> /// for IO operations
18+
#include <unordered_map> /// for unordered_map
19+
#include <vector> /// for std::vector
20+
21+
/**
22+
* @namespace backtracking
23+
* @brief Backtracking algorithms
24+
*/
25+
namespace backtracking {
26+
/**
27+
* @namespace subarray_sum
28+
* @brief Functions for the [Subset
29+
* sum](https://en.wikipedia.org/wiki/Subset_sum_problem) implementation
30+
*/
31+
namespace subarray_sum {
32+
/**
33+
* @brief The main function that implements the count of the subarrays
34+
* @param sum is the required sum of any subarrays
35+
* @param in_arr is the input array
36+
* @returns count of the number of subsets with required sum
37+
*/
38+
uint64_t subarray_sum(int64_t sum, const std::vector<int64_t> &in_arr) {
39+
int64_t nelement = in_arr.size();
40+
int64_t count_of_subset = 0;
41+
int64_t current_sum = 0;
42+
std::unordered_map<int64_t, int64_t>
43+
sumarray; // to store the subarrays count
44+
// frequency having some sum value
45+
46+
for (int64_t i = 0; i < nelement; i++) {
47+
current_sum += in_arr[i];
48+
49+
if (current_sum == sum) {
50+
count_of_subset++;
51+
}
52+
// If in case current_sum is greater than the required sum
53+
if (sumarray.find(current_sum - sum) != sumarray.end()) {
54+
count_of_subset += (sumarray[current_sum - sum]);
55+
}
56+
sumarray[current_sum]++;
57+
}
58+
return count_of_subset;
59+
}
60+
} // namespace subarray_sum
61+
} // namespace backtracking
62+
63+
/**
64+
* @brief Self-test implementations
65+
* @returns void
66+
*/
67+
static void test() {
68+
// 1st test
69+
std::cout << "1st test ";
70+
std::vector<int64_t> array1 = {-7, -3, -2, 5, 8}; // input array
71+
assert(
72+
backtracking::subarray_sum::subarray_sum(0, array1) ==
73+
1); // first argument in subarray_sum function is the required sum and
74+
// second is the input array, answer is the subarray {(-3,-2,5)}
75+
std::cout << "passed" << std::endl;
76+
77+
// 2nd test
78+
std::cout << "2nd test ";
79+
std::vector<int64_t> array2 = {1, 2, 3, 3};
80+
assert(backtracking::subarray_sum::subarray_sum(6, array2) ==
81+
2); // here we are expecting 2 subsets which sum up to 6 i.e.
82+
// {(1,2,3),(3,3)}
83+
std::cout << "passed" << std::endl;
84+
85+
// 3rd test
86+
std::cout << "3rd test ";
87+
std::vector<int64_t> array3 = {1, 1, 1, 1};
88+
assert(backtracking::subarray_sum::subarray_sum(1, array3) ==
89+
4); // here we are expecting 4 subsets which sum up to 1 i.e.
90+
// {(1),(1),(1),(1)}
91+
std::cout << "passed" << std::endl;
92+
93+
// 4rd test
94+
std::cout << "4th test ";
95+
std::vector<int64_t> array4 = {3, 3, 3, 3};
96+
assert(backtracking::subarray_sum::subarray_sum(6, array4) ==
97+
3); // here we are expecting 3 subsets which sum up to 6 i.e.
98+
// {(3,3),(3,3),(3,3)}
99+
std::cout << "passed" << std::endl;
100+
101+
// 5th test
102+
std::cout << "5th test ";
103+
std::vector<int64_t> array5 = {};
104+
assert(backtracking::subarray_sum::subarray_sum(6, array5) ==
105+
0); // here we are expecting 0 subsets which sum up to 6 i.e. we
106+
// cannot select anything from an empty array
107+
std::cout << "passed" << std::endl;
108+
}
109+
110+
/**
111+
* @brief Main function
112+
* @returns 0 on exit
113+
*/
114+
int main() {
115+
test(); // run self-test implementations
116+
return 0;
117+
}

0 commit comments

Comments
 (0)