//import java.util.ArrayList; // If you choose to use ArrayLists import java.io.PrintStream; // For enumerating solutions /* An instance of this class has methods for solving the decision, ** counting, and enumeration versions of the Subsequence Sum Problem. ** ** Authors: R. McCloskey and ** Collaborated with: ... ** Known Defects: ... */ public class SubSeqSumSolver { // instance variables // ------------------ private int[] A; // the "resident sequence/array" private PrintStream out; // the "resident sink" (where solutions // are enumerated) // constructors // ------------ /* Establishes the "resident sequence" of positive integers to ** be that defined by the given array and the "resident sink" ** to be System.out (standard output). */ public SubSeqSumSolver(int[] ary) { this(ary, System.out); } /* Establishes the "resident sequence" of positive integers to ** be that defined by the given array and the "resident sink" ** to be the given PrintStream object. */ public SubSeqSumSolver(int[] ary, PrintStream ps) { setResidentSequence(ary); setResidentSink(ps); } // observers // --------- /* Reports whether or not there exists a subsequence ** of <0,1,2,...,N-1> (where N = A.length) satisfying the condition that ** target = A[i_1] + A[i_2] + ... + A[i_k] (where A is the resident array). ** In other words, it reports whether there exists a solution to the ** problem instance (A,target). */ public boolean exists(int target) { return existsAux(target, A.length); } /* Reports the number of distinct subsequences of ** <0,1,2,...,N-1> (where N = A.length) satisfying the condition that ** target = A[i_1] + A[i_2] + ... + A[i_k] (where A is the resident array). ** In other words, it reports the number of distinct solutions to the ** problem instance (A,target). */ public int numberOf(int target) { return numberOfAux(target, A.length); } /* Sends to the "resident sink" (a String representing) every subsequence ** of <0,1,2,...,N-1> satisfying the condition that ** target = A[i_1] + A[i_2] + ... + A[i_k] (where A is the resident array). ** In other words, it enumerates all distinct solutions to the problem ** instance (A,target). */ public void enumerate(int target) { enumerateAux(target, A.length, new RecursiveListEmpty()); // Alternative to above, if you choose to use an ArrayList: // enumerateAux(target, A.length, new ArrayList()); } // private methods auxiliary to the observers // ------------------------------------------ /* Reports whether or not there exists a subsequence ** of <0,1,2,...,n-1> satisfying the condition that ** target = A[i_1] + A[i_2] + ... + A[i_k] (where A is the resident array). ** In other words, it reports whether there exists a solution to the ** (generalized) problem instance (A,n,target). */ private boolean existsAux(int target, int n) { return false; // STUB! } /* Reports the number of distinct subsequences of ** <0,1,2,...,n-1> satisfying the condition that ** target = A[i_1] + A[i_2] + ... + A[i_k] (where A is the resident array). ** In other words, it reports the number of distinct solutions to the ** (generalized) problem instance (A,n,target). */ private int numberOfAux(int target, int n) { return -15; // STUB! } /* Sends to the "resident sink" (Strings representing) all subsequences of ** <0,1,...,N-1> that are formed by appending a solution to (generalized) ** problem instance (A,n,target) with 'partialSol' (the "accumulating ** parameter"). (It is assumed that the sum of the elements of A[] in ** the locations included in 'partialSol' is M-target, where M was the ** target value originally given to the enumerate() method.) */ private void enumerateAux(int target, int n, RecursiveList partialSol) { //Next line replaces line above if you choose to use an ArrayList //private void enumerateAux(int target, int n, ArrayList partialSol) { // STUB! } // mutators // -------- /* Sets the resident sequence to be that described by the given array. ** An IllegalArgumentException is thrown if there are any negative ** values in the array. */ public void setResidentSequence(int[] ary) { if (allPositive(ary)) { A = ary.clone(); } else { throw new IllegalArgumentException("Non-positive values in array!"); } } /* Sets the resident sink to be the given PrintStream object. */ public void setResidentSink(PrintStream ps) { out = ps; } // private utilty methods // ---------------------- /* Reports whether or not every element in the given array is ** positive (i.e., greater than zero). */ private boolean allPositive(int[] a) { int i; for (i=0; i != a.length && a[i] > 0; i++) { } return i == a.length; } /* Returns the sum A[i_1] + A[i_2] + ... + A[i_k], ** where list = . */ private int sumOf(RecursiveList list) { if (list.isEmpty()) { return 0; } else { return A[list.headOf()] + sumOf(list.tailOf()); } } // What follows is the ArrayList version of the method above. /* Returns the sum A[i_1] + A[i_2] + ... + A[i_k], ** where list = . */ /* private int sumOf(ArrayList list) { int sumSoFar = 0; for (int i : list) { sumSoFar = sumSoFar + A[i]; } return sumSoFar; } */ /* Prints the elements of the given list to the resident sink. */ private void print(RecursiveList list) { //Line below replaces line above if you use an ArrayList //private void print(ArrayList list) { out.print(list); out.printf("; Sum = %d\n", sumOf(list)); } }