2021-06-28 19:50:08 +08:00
/**
* @ file
2021-07-05 08:47:06 +08:00
* @ brief Program to Count number of subsets ( both continuous and non - continuous subarrays ) with a given sum
2021-06-28 19:50:08 +08:00
*
* @ details Subset problem ( https : //en.wikipedia.org/wiki/Subset_sum_problem)
* @ author [ Swastika Gupta ] ( https : //github.com/swastyy)
*/
2021-06-28 20:16:14 +08:00
# include <cassert> /// for assert
# include <iostream> /// for io operations
# include <vector> /// for std::vector
2021-06-28 19:50:08 +08:00
/**
* @ namespace backtracking
* @ brief subset sum algorithm
*/
namespace backtracking {
/**
* @ namespace Subsets
2021-07-05 08:47:06 +08:00
* @ brief Functions for counting subsets ( both continuous and non - continuous subarrays ) in a given array with a given sum
* Time Complexity : O ( n * 2 ^ n ) , where ‘ n ’ is the number of elements in the given array .
2021-06-28 19:50:08 +08:00
*/
namespace Subsets {
/**
* @ brief The main function implements count of subsets
* @ param sum is the required sum of any subset
* @ param in_arr is the input array
* @ returns count of the number of subsets with required sum
*/
2021-06-28 20:15:32 +08:00
std : : uint64_t subset_sum ( int sum , const std : : vector < int > & in_arr ) {
2021-06-30 02:49:35 +08:00
int nelement = in_arr . size ( ) ;
2021-06-28 20:16:14 +08:00
int count_of_subset = 0 ;
2021-06-28 19:50:08 +08:00
2021-06-28 20:16:14 +08:00
for ( int i = 0 ; i < ( 1 < < ( nelement ) ) ; i + + ) {
2021-06-30 01:41:09 +08:00
int check = 0 ;
2021-06-28 20:16:14 +08:00
for ( int j = 0 ; j < nelement ; j + + ) {
if ( i & ( 1 < < j ) ) {
2021-06-30 01:41:09 +08:00
check + = ( in_arr [ j ] ) ;
2021-06-28 20:16:14 +08:00
}
}
if ( check = = sum ) {
count_of_subset + + ;
}
}
return count_of_subset ;
2021-06-28 19:50:08 +08:00
}
} // namespace Subsets
} // namespace backtracking
/**
* @ brief Test implementations
* @ returns void
*/
static void test ( ) {
// Test 1
std : : cout < < " 1st test " ;
2021-06-30 01:41:50 +08:00
std : : vector < int > array1 = { - 7 , - 3 , - 2 , 5 , 8 } ; // input array
2021-07-05 08:47:06 +08:00
assert ( backtracking : : Subsets : : subset_sum ( 0 , array1 ) = = 2 ) ; // first argument in subset_sum function is the required sum and second is the input array
2021-06-28 19:50:08 +08:00
std : : cout < < " passed " < < std : : endl ;
// Test 2
std : : cout < < " 2nd test " ;
2021-06-30 01:41:09 +08:00
std : : vector < int > array2 = { 1 , 2 , 3 , 3 } ;
2021-07-05 08:47:06 +08:00
assert ( backtracking : : Subsets : : subset_sum ( 6 , array2 ) = = 3 ) ; // here we are expecting 3 subsets which sum up to 6 i.e. {(1,2,3),(1,2,3),(3,3)}
2021-06-28 19:50:08 +08:00
std : : cout < < " passed " < < std : : endl ;
// Test 3
std : : cout < < " 3rd test " ;
2021-06-30 01:41:09 +08:00
std : : vector < int > array3 = { 1 , 1 , 1 , 1 } ;
2021-07-05 08:47:06 +08:00
assert ( backtracking : : Subsets : : subset_sum ( 1 , array3 ) = = 4 ) ; // here we are expecting 4 subsets which sum up to 1 i.e. {(1),(1),(1),(1)}
2021-06-28 19:50:08 +08:00
std : : cout < < " passed " < < std : : endl ;
// Test 4
std : : cout < < " 4th test " ;
2021-06-30 01:41:09 +08:00
std : : vector < int > array4 = { 3 , 3 , 3 , 3 } ;
2021-07-05 08:47:06 +08:00
assert ( backtracking : : Subsets : : subset_sum ( 6 , array4 ) = = 6 ) ; // here we are expecting 6 subsets which sum up to 6 i.e. {(3,3),(3,3),(3,3),(3,3),(3,3),(3,3)}
2021-06-30 01:41:09 +08:00
std : : cout < < " passed " < < std : : endl ;
// Test 5
std : : cout < < " 5th test " ;
std : : vector < int > array5 = { } ;
2021-07-05 08:47:06 +08:00
assert ( backtracking : : Subsets : : subset_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-06-28 19:50:08 +08:00
std : : cout < < " passed " < < std : : endl ;
}
/**
* @ brief Main function
* @ returns 0 on exit
*/
int main ( ) {
test ( ) ; // execute the test
return 0 ;
}