This program finds the exact pairs from a set of numbers to form the desired sum, the program also returns the unique pairs in the end. The program also returns a nearest/closest subset to form the desired sum if no exact subset is found. You can run the program as is to see the demo and then do the modification if needed. The logic I have applied here is based on all combinations of numbers in a given set to get the desired sum, you can refer to inline comments for further information
package com.test;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
*
* @author ziya sayed
* @email : sayedziya@gmail.com
*/
public class SumOfSubsets{
// private static int[] numbers= {1,1,2,2,3,4};//set of numbers
private static int[] numbers= {18,17,1};//set of numbers
// private static final int SUM = 4;//desired sum
private static final int SUM = 20;//desired sum
public static void main(String[] args) {
String binaryCount="";
int[] nos=new int[numbers.length];
//input set, and setting binary counter
System.out.print("Input set numbers are : ");
for (int no : numbers) {
if (no<=SUM) {
System.out.print(no+" ");
nos[binaryCount.length()]=no;
binaryCount+=1; //can we use sring builder or string.format
}
}
System.out.println();
Arrays.sort(nos);//sort asc
int totalNos = binaryCount.length();
String subset=""; //chosen subset
int subsetSum=0;//to temp hold sum of chosen subset every iteration
String nearestSubset="";//chosen closest subset if no exact subset
int nearestSubsetSum=0;//to hold sum of chosen closest subset
Set<String> rs = new HashSet<String>();//to hold result, it will also avoide duplicate pairs
for (int i = Integer.parseInt(binaryCount, 2) ; i >0;i-- ) {//for all sum combinations
// System.out.println(i);
binaryCount=String.format("%1$#" + totalNos + "s", Integer.toBinaryString(i)).replace(" ","0");//pad 0 to left if number is less than 6 digit binary for proper combinations
subset="";
subsetSum=0;
for (int j=0 ;j<totalNos; j++) {//for active combinations sum
if (binaryCount.charAt(j)=='1') {
subset+=nos[j]+" ";
subsetSum+=nos[j];
}
}
if (subsetSum == SUM) {
// System.out.println(subset);//we can exit here if we need only one set
rs.add(subset);
}
else{//use this for subset of numbers with nearest to desired sum
if (subsetSum < SUM && subsetSum > nearestSubsetSum && rs.isEmpty()) {
nearestSubsetSum = subsetSum;
nearestSubset = subset;
}
}
}
if (rs.isEmpty()) {
System.out.println("Nearest Subset of "+SUM);
System.out.println(nearestSubset);
}
else{
System.out.println("Exact Subset of "+SUM);
System.out.println(rs);//unique sub sets to remove duplicate pairs
}
}
}