package rebelsky.exam2.solutions; /** * Something that helps us count coints. * * @author Samuel A. Rebelsky * @author CSC152 2004F */ public class CoinCounter { // +--------+-------------------------------------------------- // | Fields | // +--------+ /** * The valid coin values. */ int[] denominations; /** * The number of recursive calls. */ int calls; /** * Yay! Stuff to make us more efficient. */ int cache[]; // +--------------+-------------------------------------------- // | Constructors | // +--------------+ /** * Build a new coin counter for a particular set of denominations. * * @pre * The values in _denominations must be stored in * decreasing order. * @pre * All values in _denominations must be positive. */ public CoinCounter(int[] _denominations) { this.denominations = _denominations; } // CoinCounter(int[]) // +----------------+------------------------------------------ // | Public Methods | // +----------------+ /** * Determine the fewest number of coins necessary to * make a particular price. * * @exception Exception * If it is not possible to make that price. */ public int fewestCoins(int price) throws Exception { ++this.calls; // Simple solution: No coins needed for no price. if (price == 0) return 0; // Make sure the cache is big enough. if ((cache == null) || (cache.length <= price)) { cache = new int[price+1]; } // Check the cache. if (cache[price] != 0) { if (cache[price] == Integer.MAX_VALUE) throw new Exception(""); else return cache[price]; } // Fewest represents the fewest coins we've done so far int fewest = Integer.MAX_VALUE; for (int i = 0; i < this.denominations.length; i++) { int coin = this.denominations[i]; if (coin <= price) { try { int sub = this.fewestCoins(price-coin); if (sub+1 < fewest) fewest = sub+1; } // try catch (Exception e) { // It's okay we failed, we'll just // try a different denomination. } // catch } // if (coin <= price) } // for // Update the cache cache[price] = fewest; // Make sure that we found a solution if (fewest == Integer.MAX_VALUE) throw new Exception("Can't make change for " + price); return fewest; } // fewestCoins(int) /** * Reset the count of number of calls to fewestCoins. */ public void resetCalls() { this.calls = 0; } // resetCalls() /** * Get the count of the number of calls to fewestCoins. */ public int getCalls() { return this.calls; } // getCalls() } // class CoinCounter