2021-06-28 17:20:08 +05:30
/**
* @ file
2021-07-07 03:13:55 +00:00
* @ brief Implementation of the [ Subset
* Sum ] ( https : //en.wikipedia.org/wiki/Subset_sum_problem) problem.
2021-07-07 08:42:46 +05:30
* @ details
* We are given an array and a sum value . The algorithms find all
2021-07-07 03:13:55 +00:00
* the subsets of that array with sum equal to the given sum and return such
* subsets count . This approach will have exponential time complexity .
2021-07-07 08:45:32 +05:30
* @ author [ Swastika Gupta ] ( https : //github.com/Swastyy)
2021-06-28 17:20:08 +05:30
*/
2021-06-28 12:16:14 +00:00
# include <cassert> /// for assert
# include <iostream> /// for io operations
# include <vector> /// for std::vector
2021-06-28 17:20:08 +05:30
/**
* @ namespace backtracking
2021-07-07 08:42:55 +05:30
* @ brief Backtracking algorithms
2021-06-28 17:20:08 +05:30
*/
namespace backtracking {
/**
* @ namespace Subsets
2021-07-07 03:25:20 +00:00
* @ brief Functions for the [ Subset
* Sum ] ( https : //en.wikipedia.org/wiki/Subset_sum_problem) problem.
2021-06-28 17:20:08 +05:30
*/
2021-07-07 08:44:31 +05:30
namespace subset_sum {
2021-06-28 17:20:08 +05:30
/**
* @ 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-07-10 12:48:08 +05:30
uint64_t subset_sum ( int64_t sum , const std : : vector < int64_t > & in_arr ) {
2021-06-30 00:19:35 +05:30
int nelement = in_arr . size ( ) ;
2021-06-28 12:16:14 +00:00
int count_of_subset = 0 ;
2021-06-28 17:20:08 +05:30
2021-06-28 12:16:14 +00:00
for ( int i = 0 ; i < ( 1 < < ( nelement ) ) ; i + + ) {
2021-06-29 23:11:09 +05:30
int check = 0 ;
2021-06-28 12:16:14 +00:00
for ( int j = 0 ; j < nelement ; j + + ) {
if ( i & ( 1 < < j ) ) {
2021-06-29 23:11:09 +05:30
check + = ( in_arr [ j ] ) ;
2021-06-28 12:16:14 +00:00
}
}
if ( check = = sum ) {
count_of_subset + + ;
}
}
return count_of_subset ;
2021-06-28 17:20:08 +05:30
}
2021-07-07 08:45:48 +05:30
} // namespace subset_sum
2021-06-28 17:20:08 +05:30
} // namespace backtracking
/**
* @ brief Test implementations
* @ returns void
*/
static void test ( ) {
// Test 1
std : : cout < < " 1st test " ;
2021-07-10 12:48:08 +05:30
std : : vector < int64_t > array1 = { - 7 , - 3 , - 2 , 5 , 8 } ; // input array
assert ( backtracking : : subset_sum : : subset_sum ( 0 , array1 ) = = 2 ) ; // first argument in subset_sum function is the required sum and
2021-07-07 03:25:20 +00:00
// second is the input array
2021-06-28 17:20:08 +05:30
std : : cout < < " passed " < < std : : endl ;
// Test 2
std : : cout < < " 2nd test " ;
2021-07-10 12:43:11 +05:30
std : : vector < uint64_t > array2 = { 1 , 2 , 3 , 3 } ;
2021-07-10 12:48:08 +05:30
assert ( backtracking : : subset_sum : : subset_sum ( 6 , array2 ) = = 3 ) ; // here we are expecting 3 subsets which sum up to 6 i.e.
2021-07-07 03:25:20 +00:00
// {(1,2,3),(1,2,3),(3,3)}
2021-06-28 17:20:08 +05:30
std : : cout < < " passed " < < std : : endl ;
// Test 3
std : : cout < < " 3rd test " ;
2021-07-10 12:43:20 +05:30
std : : vector < uint64_t > array3 = { 1 , 1 , 1 , 1 } ;
2021-07-10 12:48:08 +05:30
assert ( backtracking : : subset_sum : : subset_sum ( 1 , array3 ) = = 4 ) ; // here we are expecting 4 subsets which sum up to 1 i.e.
2021-07-07 03:25:20 +00:00
// {(1),(1),(1),(1)}
2021-06-28 17:20:08 +05:30
std : : cout < < " passed " < < std : : endl ;
// Test 4
std : : cout < < " 4th test " ;
2021-07-10 12:43:28 +05:30
std : : vector < uint64_t > array4 = { 3 , 3 , 3 , 3 } ;
2021-07-10 12:48:08 +05:30
assert ( backtracking : : subset_sum : : subset_sum ( 6 , array4 ) = = 6 ) ; // here we are expecting 6 subsets which sum up to 6 i.e.
2021-07-07 03:25:20 +00:00
// {(3,3),(3,3),(3,3),(3,3),(3,3),(3,3)}
2021-06-29 23:11:09 +05:30
std : : cout < < " passed " < < std : : endl ;
// Test 5
std : : cout < < " 5th test " ;
2021-07-10 12:43:45 +05:30
std : : vector < uint64_t > array5 = { } ;
2021-07-10 12:48:08 +05:30
assert ( backtracking : : subset_sum : : 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 17:20:08 +05:30
std : : cout < < " passed " < < std : : endl ;
}
/**
* @ brief Main function
* @ returns 0 on exit
*/
int main ( ) {
2021-07-07 08:45:17 +05:30
test ( ) ; // run self-test implementations
2021-06-28 17:20:08 +05:30
return 0 ;
}