DP-Coin Change result getting zero - java

So this is my code where I'm trying to find out the minimum number of coins to make up my target amount from unlimited supply of coins. My problem is instead of getting the required coin number, I'm getting 0. So how can I fix it. And sorry if i'm not clear. My english isn't that good :( . Here is my code:
import java.util.*;
public class CoinChangeDP{
public static int[] c = {1,2,2,5,5,5,10};
public static int amount = 15;
public static int[][] dp = new int[c.length+1][amount+1];
public static void main(String[] args){
System.out.println("Minimum number of coin required: "+CoinChange(0, amount));
}
public static int CoinChange(int index, int amount){
int n = c.length;
if(index>=n){
if(amount==0)
return 0;
else
return Integer.MAX_VALUE;
}
if(dp[index][amount]!=-1){
return dp[index][amount];
}
int ret1, ret2;
if(amount>=c[index]){
ret1 = 1+CoinChange(index, amount-c[index]);
}else{
ret1 = Integer.MAX_VALUE;
}
ret2 = CoinChange(index, amount);
dp[index][amount] = Math.min(ret1, ret2);
return dp[index][amount];
}
}

dp array is initialized with zeros, so when your first call checks:
if(dp[index][amount]!=-1){
return dp[index][amount];
}
it will return 0. Fill your dp array with -1 before calling coinChange() function:
for (int[] d : dp) {
Arrays.fill(d, -1);
}
System.out.println("Minimum number of coin required: "+CoinChange(0, amount));
EDIT:
Here is a fixed version of your function (follow the comments):
public static int CoinChange(int index, int amount){
int n = c.length;
// check if at any point we reached 0 amount (got a solution)
if (amount == 0) {
return 0;
}
// if we reached the end of the array and we still have amount > 0
if (index == n){
return Integer.MAX_VALUE;
}
// if we already processed the value for this index/amount
if (dp[index][amount] != -1){
return dp[index][amount];
}
int ret1, ret2;
if(amount >= c[index]){
// take this coin and stay on same index
ret1 = 1+CoinChange(index, amount-c[index]);
}else{
ret1 = Integer.MAX_VALUE;
}
// do not take this coin and go to next index
ret2 = CoinChange(index+1, amount);
dp[index][amount] = Math.min(ret1, ret2);
return dp[index][amount];
}
And about your question about unlimited supply, here the states are either take the coin and stay on the same index (take or leave on next call), or leave it and go to next index. The first function call will try taking or leaving the coin as long as it is <= the amount, so this will cover all the possible scenarios.

Related

find if given pack of coins can make a given value - coin row problem

given array of coins (int) and an int n the function need to return true if there is atleast one solution to the coin-change problem.
meaning: for array of ints> 0: [c(0) ,c(1) ,c(2) ,c(3) ,...... ,c(k)]. check if there is a solution for
the eqauation: a(0)*c(0)+ a(1)*c(1)+.....+ a(k)*c(k)= n. //n is the money we need to change
given c(0),c(1),....,c(n) >0 and a(0),a(1),....,a(n) =>0 both integers.
so I managed to make this code: the problem is that its algorithmic efficiency sucks, and this should be running on high values, and big coins array, so I need a code that is able to do this quicker.
public static boolean change(int[] coins, int n) {
boolean ans = false;
//loop running in recursion till founds ans/ passing limit
for (int i = 0; i < coins.length & (!ans); i = i + 1) {
if (n % coins[i] == 0) {
return true;
}
if (n >= coins[i]) {
ans = change(coins, n - coins[i]);
}
}
return ans;
}//O(n*k^n) solution for false ans , very bad :(
for example: for coins = {2,4,8} and n= 4111; I should get false, but the program unable to run this.
btw I would prefer this function to use recursion, but any solution/ guidnes is good :)
this is an other try doing this better but still not running as wanted.
//trying to use binary search and using divisions instead of minus
public static int iscashable(int[] coins, int n, int min, int max)
{
int check=(max+min)/2;
if(check == coins.length-1 | check == 0)
return check;
if(n/coins[check] > n% coins[check])
{
return (iscashable(coins,n,check,max));
}
else
{
return check;
}
}
public static int canchange(int[] coins, int n, int count)
{
int x=0;
int check= iscashable(coins,n,0,coins.length-count);
if(n%coins[check]==0)
{
return 0;
}
if(check==0)
{
return n;
}
if(n/coins[check] > n% coins[check])
{
x= (n/coins[check]) - (n% coins[check]);
int k= n-(coins[check]*x);
return canchange(coins, k, count+1);
}
else
{
return canchange(coins,n-coins[check],count+1);
}
}
the problem is both about runtime and number of recursion calls (with big number given, every recursion layer is coins.length^(num of layers));
I really thank you for your help!

Find if a number is in an array, and if so, how many times does it appear

The problem is there is an array of 10000 that is already filled for me. The range of numbers that will fill the array will be between 0 and 2500. The array is unsorted. My goal is to find the existence of 1320 through one linear search, and the second linear search will check how many times the number 1320 appears. The array is a random array.
I have tried setting up a linear search that will check whether the number in the array exists. I have also tried to set up the linear search that will check how many times an array exists. Neither worked, this is my first time working with arrays so I am not sure if I am even doing them correctly
public static void main(String[] args) {
// Finish adding Code
boolean DoesItExist;
int iHowMany;
final int SIZE = 10000, ENTRY = 1320;
int[] NumArray = new int[SIZE];
OwenHeading.getHeader("Assignment 9: Arrays.");
fillTheArray(NumArray, SIZE);
System.out.println("DONE");
}
public static void fillTheArray(int[] iTempArray, int SIZE) {
final int RANGE = 2500;
Random rand = new Random();
for (int index = 0; index <= SIZE - 1; index++)
iTempArray[index] = rand.nextInt(RANGE);
}
public static boolean linearSearchOne(int[] iTempArray, int SIZE, int ENTRY) {
boolean TempDoesItExist;
return TempDoesItExist;
}
public static int linearSearchTwo(int[] iTempArray, int SIZE, int ENTRY) {
int HowManyExist;
return HowManyExist;
}
public static void programOutput(boolean TempDoesItExist, int TempHowMany) {
if (TempDoesItExist)
System.out.println("does");
// Cool, you found the number 1320
else
System.out.println("does not");
// Dang, you didn't find the number 1320
}
}
I am not asking for the exact answer, just some help that will get me going into the right direction. I feel like I would be able to do this project easier if I started from scratch, but my teacher wants us to use his starter project.
Initialize your boolean and counter
Bool doesItExist = false;
Int iHowManyTimes = 0;
You can check for values in arrays in java in a linear fashion like this:
for (int number : NumArray) {
if (anItemInArray == myValue) {
doesItExist = true;
return;
}
}
afterwards do it all over again and increment your counter
for (int number : NumArray) {
if (number == ENTRY) {
iHowMany += 1;
}
}
Edit: Return statement added to first loop, as there is no reason to continue after the value is found
you can modify two methods of linear search you have in this way and that is going to work :
just declare a counter and increment it each time you find your ENTRY number.
public static boolean linearSearchOne(int[] iTempArray, int SIZE, int ENTRY) {
for (int i = 0; i < SIZE; i++) {
if (iTempArray[i] == ENTRY) {
return true;
}
}
return false
}
public static int linearSearchTwo(int[] iTempArray, int SIZE, int ENTRY) {
int HowManyExist;
for (int i = 0; i < SIZE; i++) {
if (iTempArray[i] == ENTRY) {
HowManyExist ++;
}
}
return HowManyExist;
}
It looks like you didn't call the linear search methods. For a linear search you can just do something like the following:
found=false;
howManyCounter=0;
for (int x=0, x<array.length; x++){
if (array[x]==numberYouWant){
found=true;
howManyCounter++;
}
}

Having trouble in printing the largest array number from the 20 randomly generated numbers

Ok so I been working on this assignment all day for the past 3 days but I haven't had any luck. I wasn't going to ask for help but I finally gave up. But there is also one more thing I need to implement to the code. This is what I gotta implement "Find the length of the longest continuous series of positive numbers in the array data. If the contents were: 4 5 0 2 . . . -1 88 78 66 -6. The length would be 3. For this problem, 0 is considered non-negative but not positive". Plus I have an issue where I can't print the largest int in the array of 20.
import java.util.Random;
import java.util.ArrayList;
public class arrayops {
public static int findLargest(ArrayList<Integer> nums) {
int greatestnum = nums.get(0);
for (Integer item : nums) {
if (item > greatestnum) {
greatestnum = item;
}
}
return greatestnum;
}
public static int randomData(ArrayList<Integer> nums) {
int[] array = new int [20];
Random random = new Random();
for (int i = 0; i < array.length; i++) {
array[i] = -100 + random.nextInt(201);
}
return -100 + random.nextInt(201);
}
public static void main(String[] args) {
ArrayList<Integer> nums = new ArrayList<Integer>();
nums.add(1);
nums.add(4);
nums.add(13);
nums.add(43);
nums.add(-25);
nums.add(17);
nums.add(22);
nums.add(-37);
nums.add(29);
System.out.println("The Greatest Number from the hardcoded numbers " + findLargest(nums));
System.out.println("The Greatest number from the random numbers " + randomData(nums));
}
}
The findLargest method:
public static int findLargest(ArrayList<Integer> nums) {
int greatestnum = 0;
int greatestLen = 0;
for (Integer item : nums) {
if (item > 0) {
greatestLen++ ;
if(greatestLen > greatestnum)
greatestnum = greatestLen;
}
else
greatestLen = 0;
}
return greatestnum;
}
Logic used:
Keep the length of the longest chain encountered, and the length of current chain, in two separate variables (greatestnum and greatestLen respectively)
Increment greatestLen every time a positive number is encountered. If the number if less than or equal to zero, reset this count.
If the length of current chain is greater than the previous longest chain, sent the longest chain size to current chain size.
The problem is you created a list with random numbers but never put that list into the findLargest method. You also never created a method to find the consecutive positive numbers. If you didn't know how to go about coding it, I recommend drawing out an algorithm on paper.
Largest value in ArrayList...
public static int findL(ArrayList<Integer> nums)
{
int top = nums.get(0);
for(int i = 0; i<nums.size(); i++)
{
if(nums.get(i)>top)
{
top = nums.get(i);
}
}
return top;
}
Largest number of consecutive positives...
public static int positiveString(ArrayList<Integer> nums)
{
int longest = 0;
int count = 0;
for(int i = 0; i<nums.size(); i++)
{
if(nums.get(i) > 0)
{
count++;
}
else
{
if(longest<count)
{
longest = count;
}
count = 0;
}
}
return longest;
}
If you want to arrange the numbers into order you can simply use java.util.TreeSet. Then use the method last() to get the largest number.
public static int findLargest(ArrayList<Integer> nums) {
return new TreeSet<Integer>(nums).last();
}

Find primefactors Java

I am new to JAVA programming and I am having hard time doing this lab
import java.util.*;
public class FindPrimes
{
private static ArrayList<Integer> myList = new ArrayList();
//post: returns true if value is a prime number
public static boolean isPrime(int value)
{
if(value < 2 || value % 2 == 0)
return false;
if(value == 2)
return true;
for (int i = 3; i * i <= value; i += 2)
if (value % i == 0)
return false;
return true;
//temporary return so program compiles
}
//post: returns the index of the first non-prime number in myList.
// returns -1 if all numbers are prime
private static int findNotPrime()
{
for(int i=0; i<myList.size(); i++){
if(!isPrime(myList.get(i)))
return i;
}
/*ex: [60] will return 0
[2,30] will return 1
[2,2,15] returns 2
[2,2,3,5] returns -1
*/
return -1; //temporary return so program compiles
}
//post: returns the smallest factor of a number
private static int findSmallestFactor(int num)
{
for (int i = 2; i*i<= num; i++) {
if (num % i == 0)
return i;
}
/* ex:findSmallestFactor(8) -> 2
findSmallestFactor(9) -> 3
findSmallestFactor(7) -> 7
*/
return -1; //temporary return so program compiles
}
//post: recursive method that places the prime factorization into myList
//
private static void generateList()
{
//generateList();
int var = findNotPrime();
if(var != -1){
int n = findSmallestFactor(myList.get(var));
myList.set(var, n);
myList.add(myList.get(var)/n);
generateList();
}
}
/* Hint: Check the list to find the first non-prime factor.
If all the numbers are prime, you are done.
Otherwise, * find the smallest factor of the first non-prime and its cofactor.
* replace the first non-prime with its smallest factor and add the cofactor to the end
* repeat the whole process */
//post: calcualtes the prime factorization of number and returns the list containing factors
public static ArrayList<Integer> calculateFactors(int number)
{
/* place number in myList, generate the prime factorizations and return the list.*/
myList.add(new Integer(number));
//System.out.println(myList);
generateList();
return myList;
}
public static void main(String[] arg)
{
System.out.println(8 + ":" + calculateFactors(8));
myList.clear();
System.out.println(60 + ":" + calculateFactors(60));
myList.clear();
System.out.println(75 + ":" + calculateFactors(75));
}
}
The error code I get is
"Exception in thread "main" java.lang.StackOverflowError"
I have tested all the methods and they all seem to be working. I don't know why this happens.
You call generateList inside itself, causing an infinite recursion thus your stack overflows.
Don't know if you have figured out your task yet. But I did this task since it seemed like fun and since I've never done it before and.
What is the rules for answering a thread the asking person has solved already? Well.. it's easier to get forgiveness than permission...
The problem is mainly in generateList where you don't "save" a temp variable. This can be solved like this:
if(var != -1){
int temp=myList.get(var);
int n = findSmallestFactor(temp);
myList.set(var, n);
myList.add(temp/n);
generateList();
}
Other than that you have to make a small change in isPrime method. For instance if you check if 2 is a prime it will say no, when in fact 2 is a prime number.

Printing which coins are used to make a given amount

I am trying to use recursion to find the minimum amount of coins to make a given amount. I have code that is able to list the minimum amount of coins required, but I can't seem to find a way to print off which coins were used to come up with the solution. I've searched and found similar examples, but I can't seem to properly apply it to this.
Here is what I have thus far:
import java.util.*;
public class Coins{
public static int findMinCoins(int[] currency, int amount) {
int i, j, min, tempSolution;
min = amount;
for (i = 0; i < currency.length; i++) {
if (currency[i] == amount) {
return 1;
}
}
for (j = 1; j <= (amount / 2); j++) {
tempSolution = findMinCoins(currency, j) + findMinCoins(currency, amount - j);
if (tempSolution < min) {
min = tempSolution;
}
}
return min;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int[] USA =
{1, 5, 10, 25, 50};
System.out.println("Please enter an integer amount.");
int amount = in.nextInt();
int minCoins = findMinCoins(USA, amount);
System.out.println("The minimum number of coins to make " + amount + " in United States currency is " + minCoins + ".");
System.out.println("The coins used were:");
/*Print coins used to find minCoins.*/
in.close();
}
}
An example of the code running thus far:
Please enter an integer amount.
17
The minimum number of coins to make 17 in United States currency is 4.
The coins used were:
If someone could give me some insight on how to do this, it would be much appreciated.
I think this should totally work with what you want to achieve. Just call the public static int findMinCoins(arg1, arg2) and it will output you the minimum number of coins and all the particular coins(It will show times the number of its occurrence) used using recursive algorithms.
public static int findMinCoins(int[] currency, int amount) {
int min = findMinCoins(currency, amount, 0);
System.out.print("The coins used were: ");
return min;
}
private static int findMinCoins(int[] currency, int amount, int min){
int number, value1, value2;
int min1 = min;
for(int i=currency.length-1; i>=0; i--) {
if (amount>=currency[i]){
amount = amount - currency[i];
System.out.print(currency[i] + " ");
min1 = findMinCoins(currency, amount, min1);
return ++min1;
}
}
return min1;
}
Here is a recursive code (working, but need a fix ...).
The idea is to pass and array with all coins {1,5,10,25,50} and recursively call from left to right (until end of array)
NOTES :
There is a little bug in the output
The number is passed as array of 1 element instead of a primitive int. (this is to have a reference type to keep its value through all recursive calls :
public class coins {
public static void main(String[] args) {
// arrays of coin types
int[] coinTypes = { 0, 1, 5, 10, 25, 50 };
// arrays are references, so changing them
// inside the recursive function will 'really' change
int[] price = {11}; // sample input
tryBigger(price, coinTypes, 0);
}
// tries to see if higher coin is possible by passing array
// of coin types and recursively call until the end of array
public static void tryBigger(int[] price, int[] theCoins, int index) {
if (index < theCoins.length-1){
// until last element
if (price[0] > theCoins[index]){
tryBigger(price, theCoins, ++index);
}
}
// find amount of this coin
int thisCoin = price[0]/theCoins[index];
// remove the amount already got before
price[0] = price[0] - thisCoin*theCoins[index];
System.out.println(thisCoin + " coins of " + theCoins[index]);
return;
}
}
In the code you offer, either the number 1 or min are returned by the recursive function. Keeping with this method, one way you could obtain the list of coins is by altering the return variable to include both coins and count.
Here's an example of the general idea; since I don't know about programming in Java, I'll leave the implementation to you.
if (currency[i] == amount){
return [1,i];
...
temp1 = findMinCoins(currency,j);
temp2 = findMinCoins(currency,amount - j);
if(temp1[0] + temp2[0] < min[0]){
min = [temp1[0] + temp2[0]] concatenated with temp1[1..] and temp2[1..]
Here you go, you have a test and the function is below. Notice that edge cases are not handled, such as empty currency or negative amount.
It is assumed that the currency array is sorted. If not, sort it with Arrays.sort(currency).
public class FindMinimumCoinsTest {
#Test
public void test() throws Exception {
int[] USA = { 1, 5, 10, 25, 50 };
assertEquals(2, findMinCoins(USA, 11));
assertEquals(4, findMinCoins(USA, 8));
assertEquals(4, findMinCoins(USA, 111));
assertEquals(3, findMinCoins(USA, 27));
}
public static int findMinCoins(int[] currency, int amount) {
int coins = 0;
int sum = 0;
int value, n;
for (int i = currency.length - 1; i >= 0; i--) {
value = currency[i];
n = (amount - sum) / value;
if (n > 0) {
coins += n;
sum += n * value;
}
}
return coins;
}
}
Also, no need for recursion using this method ;)
I was working on something similar and this is what I came up with. You can hold the used coins in a separate array and have a helper function print the last used coins recursively. If you want to return a list or a string you can just have the helper create and return one.
/**
* FIND MINIMAL NUMBER OF COINS TO MAKE CHANGE, WITH CHANGE VALUES: 1, 2, 5, 10, 20, 50, 100, 200
*
* #param change The amount of change we need to give
* #return Minimal amount of coins used
*/
public static int minimalNumberOfCoinsToMakeChange(int change) {
int[] denominations = {1, 2, 5, 10, 20, 50, 100, 200};
int[] dp = new int[change + 1];
int[] origins = new int[change+1];
dp[0] = 0;
for (int i = 1; i <= change; i++) {
dp[i] = Integer.MAX_VALUE;
for (int coin : denominations) {
if (i - coin < 0) {
continue;
}
dp[i] = Math.min(dp[i], 1 + dp[i - coin]);
origins[i] = coin;
}
}
if (dp[change] == Integer.MAX_VALUE) {
return -1;
}
printPath(origins);
return dp[change];
}
/**
* HELPER FUNCTION - GET PATH
*
* #param origins Array with origins from main function
*/
private static void printPath(int[] origins) {
int last = origins[origins.length-1];
System.out.println(last);
origins = Arrays.copyOfRange(origins,0,origins.length-last);
if (origins.length-1 > 0){
printPath(origins);
}
}
I hardcoded the array of denominations in this example, but you should be able to remove it and pass another as argument. It is not the most efficient way, but might be helpful to people who are only just getting into dynamic programming, like I am. Cheers!

Categories