2021-07-06 20:08:07 +05:30
/**
* @ file
* @ brief We are given with an array and a sum value . The algorithms find all
2021-07-06 14:38:56 +00:00
* the subarrays of that array with sum equal to given sum and return such
* subarrays count . This approach will have \ f $ O ( n ) \ f $ time complexity and
* \ f $ O ( n ) \ f $ space complexity . NOTE : In this problem , we are only refering to
* the continuous subsets as subarrays everywhere . Subarrays can be created
* using deletion operation at the end or the front of an array only . The parent
* array is also counted in subarrays having 0 number of deletion operations .
* @ details Subset sum ( only continuous subsets ) problem
* ( https : //en.wikipedia.org/wiki/Subset_sum_problem)
2021-07-10 13:12:43 +05:30
* @ author [ Swastika Gupta ] ( https : //github.com/Swastyy)
2021-07-06 20:08:07 +05:30
*/
# include <cassert> /// for assert
2021-07-10 13:05:15 +05:30
# include <iostream> /// for IO operations
2021-07-06 20:08:07 +05:30
# include <unordered_map> /// for unordered_map
2021-07-06 14:38:56 +00:00
# include <vector> /// for std::vector
2021-07-06 20:08:07 +05:30
/**
* @ namespace backtracking
* @ brief subarray sum algorithm
*/
namespace backtracking {
/**
2021-07-10 13:12:43 +05:30
* @ namespace subarraySum
* @ brief Functions for the [ Subset sum ] ( https : //en.wikipedia.org/wiki/Subset_sum_problem) implementation
2021-07-06 20:08:07 +05:30
*/
2021-07-10 13:12:43 +05:30
namespace subarraySum {
2021-07-06 20:08:07 +05:30
/**
* @ brief The main function implements count of subarrays
* @ param sum is the required sum of any subarrays
* @ param in_arr is the input array
* @ returns count of the number of subsets with required sum
*/
2021-07-10 13:12:43 +05:30
uint64_t subarray_sum ( int sum , const std : : vector < int > & in_arr ) {
2021-07-06 20:08:07 +05:30
int nelement = in_arr . size ( ) ;
int count_of_subset = 0 ;
int current_sum = 0 ;
2021-07-06 14:38:56 +00:00
std : : unordered_map < int , int > sumarray ; // to store the subarrays count
// frequency having some sum value
2021-07-06 20:08:07 +05:30
for ( int i = 0 ; i < nelement ; i + + ) {
current_sum + = in_arr [ i ] ;
2021-07-06 14:38:56 +00:00
2021-07-06 20:08:07 +05:30
if ( current_sum = = sum ) {
count_of_subset + + ;
}
// If in case current_sum is greater than the required sum
if ( sumarray . find ( current_sum - sum ) ! = sumarray . end ( ) ) {
count_of_subset + = ( sumarray [ current_sum - sum ] ) ;
}
sumarray [ current_sum ] + + ;
}
return count_of_subset ;
}
2021-07-10 13:12:43 +05:30
} // namespace subarraySum
2021-07-06 20:08:07 +05:30
} // namespace backtracking
/**
2021-07-10 13:03:56 +05:30
* @ brief Self - test implementations
2021-07-06 20:08:07 +05:30
* @ returns void
*/
static void test ( ) {
// Test 1
std : : cout < < " 1st test " ;
std : : vector < int > array1 = { - 7 , - 3 , - 2 , 5 , 8 } ; // input array
2021-07-10 13:12:43 +05:30
assert ( backtracking : : subarraySum : : subarray_sum ( 0 , array1 ) = = 1 ) ; // first argument in subarray_sum function is the required sum and second is the input array, answer is the subarray {(-3,-2,5)}
2021-07-06 20:08:07 +05:30
std : : cout < < " passed " < < std : : endl ;
// Test 2
std : : cout < < " 2nd test " ;
std : : vector < int > array2 = { 1 , 2 , 3 , 3 } ;
2021-07-10 13:12:43 +05:30
assert ( backtracking : : subarraySum : : subarray_sum ( 6 , array2 ) = = 2 ) ; // here we are expecting 2 subsets which sum up to 6 i.e. {(1,2,3),(3,3)}
2021-07-06 20:08:07 +05:30
std : : cout < < " passed " < < std : : endl ;
// Test 3
std : : cout < < " 3rd test " ;
std : : vector < int > array3 = { 1 , 1 , 1 , 1 } ;
2021-07-10 13:12:43 +05:30
assert ( backtracking : : subarraySum : : subarray_sum ( 1 , array3 ) = = 4 ) ; // here we are expecting 4 subsets which sum up to 1 i.e. {(1),(1),(1),(1)}
2021-07-06 20:08:07 +05:30
std : : cout < < " passed " < < std : : endl ;
// Test 4
std : : cout < < " 4th test " ;
std : : vector < int > array4 = { 3 , 3 , 3 , 3 } ;
2021-07-10 13:12:43 +05:30
assert ( backtracking : : subarraySum : : subarray_sum ( 6 , array4 ) = = 3 ) ; // here we are expecting 3 subsets which sum up to 6 i.e. {(3,3),(3,3),(3,3)}
2021-07-06 20:08:07 +05:30
std : : cout < < " passed " < < std : : endl ;
// Test 5
std : : cout < < " 5th test " ;
std : : vector < int > array5 = { } ;
2021-07-10 13:12:43 +05:30
assert ( backtracking : : subarraySum : : subarray_sum ( 6 , array5 ) = = 0 ) ; // here we are expecting 0 subsets which sum up to 6 i.e. we cannot select anything from an empty array
2021-07-06 20:08:07 +05:30
std : : cout < < " passed " < < std : : endl ;
}
/**
* @ brief Main function
* @ returns 0 on exit
*/
int main ( ) {
test ( ) ; // execute the test
return 0 ;
}