Home > Software design >  Trying to change a loop to a recursive method. Having some toruble
Trying to change a loop to a recursive method. Having some toruble

Time:12-15

I need to include recursion into my final project. It was recommended to me to simply change one of my loops to a recursive method. Here's what I have so far. It returning a value of 0 every time.

public static double GetCostTotal(Liquor[] inv, int index)  {
        if ( index >= inv.length) return 0;
        else return GetCostTotal(inv, index   1);
}

Here's where I call it in my main method:

//beer. regular 1d array 
        System.out.println("\nNow for beer. How many beers are you taking inventory of?: ");
        int sizeBeers = keyboard.nextInt();
        Beer[] invBeers = new Beer[sizeBeers];        
        for (int i = 0; i < invBeers.length; i  )   {
            invBeers [i] = new Beer();
            System.out.println("Enter product name: ");
            invBeers [i].setLiquorName(keyboard.next());
            System.out.println("Enter the count: ");
            invBeers [i].setLiquorCount(keyboard.nextDouble());
            System.out.println("Enter the cost: ");
            invBeers [i].setLiquorCost(keyboard.nextDouble());
        }        
        //calls GetCostTotal method and passes invBeers array 
        double beerCost = GetCostTotal(invBeers, sizeBeers);
        System.out.println("The total cost of the beer inventory is: $"   beerCost);

I'm still trying to find my own solution but obviously looking for some help from you guys too. Thanks!

CodePudding user response:

Just add the total cost of the current item and the result of the recursive call:

public static double GetCostTotal(Liquor[] inv, int index)  {
        if (index >= inv.length) return 0;
        else return (inv.getLiquorCount() * inv.getLiquorCost())   GetCostTotal(inv, index   1);
}

Note: this is not tail recursive, and, anyway, Java doesn't optimize tail calls, so if your array is too long, you'll get a StackOverflowError.

If you modify it to use an accumulator, as in hfontanez's answer, and write it in a language and on a platform that does proper tail call elimination, it will not overflow. Hopefully one day Java will add TCO/TCE.

CodePudding user response:

Your recursive method should be something like this:

public static double GetCostTotal(Liquor[] inv, int index, double total) {
    if (index >= inv.length)
        return total;
    else
        total = inv[index].amount() * inv[index].cost();
        return GetCostTotal(inv, index   1, total);
}

You can see that total is a parameter passed to the function so that you could effectively accumulate the sum of the costs. Otherwise, you will overwrite the amount with each call. Second, the else clause is performing the necessary calculation.

Lastly, your initial call was triggering the default (base) case because you were passing the length of the array instead of starting at zero.

    double beerCost = GetCostTotal(invBeers, 0, 0);

Since your recursive call is incrementing index by one, you need to pass zero for the index and zero for the total.

If you do this, you should get the right result. This is my sample input and result:

Now for beer. How many beers are you taking inventory of?: 
3
Enter product name: 
Bud
Enter the count: 
1
Enter the cost: 
2
Enter product name: 
Miller
Enter the count: 
2
Enter the cost: 
3
Enter product name: 
Michelob
Enter the count: 
3
Enter the cost: 
4
The total cost of the beer inventory is: $20.0

You can see that for the first iteration the cumulative cost is 2.00 (12), for the second is 6.00 (23), and for the last is 12.00 (3*4), which totals 20.00 (2 6 12)

NOTE: I created a Java record for Beer instead of a conventional class. That's why the methods I am calling in GetCostTotal are cost() and amount(). You will need to change them to match your correct method names OR change Liquor and Beer to be Java records which I HIGHLY recommend if you are using the latest Java.

CodePudding user response:

Solution here. Wasn't performing necessary calculations and was calling the method incorrectly.

public static double GetCostTotal(Liquor[] inv, int index, double totalCost)  {
        if ( index >= inv.length) return totalCost;
        else totalCost = inv[index].getLiquorCount()*inv[index].getLiquorCost();
        return GetCostTotal(inv, index   1, totalCost);
    }

double beerCost = GetCostTotal(invBeers, 0, 0);
        System.out.println("The total cost of the beer inventory is: $"   beerCost);
  • Related