this is my first programming course, and i want to make sure i am doing this problem correctly. if you could check over my work it would be greatly appreciated.
Write a method to compute and return the balance for a checking account, given the starting balance and an array of Check objects. You may assume that the Check class already exists and has a method to get the amount from a particular check object called: double getAmount()
The array is not full, and may have gaps in it – make sure you test to see if there is an object there before you try to access it! Make your code work for any length array!
The header for the method is provided for you:
public double computeBalance(double startingBalance, Check[] register) {
int i = 0; // i must be initialized and declared somewhere at least
double total = 0.0;
while ((i >= check.length) && check[i] != null) { // is >= correct? you do i++!
total = (total + getAmount(check[i])); // should you add/compute somewhere
// the given amounts
i++;
}
System.out.println(total);
}
Forget programming for a second. If I told you "Here's the starting balance in your account." and then handed you a bunch of checks and told you to compute the ending balance, how would you do it? Once you understand that, you can start to work on the programming problem.
Some questions:
Where are you tracking the account balance?
What will happen in your loop if one of the slots in register is empty (i.e. null)?
What is this check variable in your loop? Where is it being declared? Is check really what it should be called?
The function is declared as returning double. What are you returning?
Have you tried compiling your code? What happens?
I understand that you are asking for more than for the solution itself but there are obviously better people to guide you. You can use my example as a reference to what others are explaining to you.
public double computeBalance(double startingBalance, Check[] register) {
// let's start off from the starting balance
double total = startingBalance;
// go over all elements starting from 0
for (int i = 0; i < check.length; i++) {
// make sure you did not encounter null element
if (register[i] != null) {
// increase the total by the amount of the Check
total += register[i].getAmount();
}
}
// and finally return the resulting value
return total;
}
The execution will end when you reach a gap. Use an if-statement inside the loop for the null check instead.
If you could run your code through a compiler (which it sounds like you can't, or at least aren't being encouraged to), it would tell you that it has no idea what i, check, or getAmount are.
A method body that doesn't refer to the method parameters is generally missing something -- especially if the parameter declarations were given by your instructor.
Look again at your loop condition. What is the value of i going to be at the beginning?
Related
I just started learning how to program in Java a month ago. I am trying to make my robot (karel) put a beeper the amount of times that is indicated in the "put" integer only, not the total amount the object has. However, it is not a set number and karel.putBeeper(put); does not get accepted in the compiler due to the class not being applied to given types. Any help would be greatly appreciated, and I am starting to understand why Stack Overflow is a programmer's best friend lol. Note: I might not respond to to any helpful tips until tomorrow.
import java.io.*;
import java.util.*;
public class Lab09 {
public static void main(String[]args) {
Scanner input = new Scanner(System.in);
System.out.println("Which world?");
String filename = input.nextLine();
World.readWorld(filename);
World.setSize(10,10);
World.setSpeed(6);
Robot karel = new Robot(1,1,World.EAST,0);
int pick=0;
int put=0;
for(int i=0; i<8; i++) {
while(karel.onABeeper()) {
karel.pickBeeper();
pick++;
karel.move();
}
for(i=0; pick>i; pick--) {
put++;
}
if(!karel.onABeeper()) {
karel.move();
}
while(karel.onABeeper() && put>0) {
karel.putBeeper(put);
}
}
}
}
If I got your question right, you're trying to putBeeper put times, which is done by the following code:
while (karel.onABeeper() && put > 0) {
karel.putBeeper(put);
}
The issue I see here is that you're not changing the value of put after calls to putBeeper, hence this while loop will never terminate: for instance, if the value of put was 5 during the first loop iteration, it will always remain 5, which is larger than 0. Also, as you've mentioned, putBeeper doesn't take any arguments, hence trying to pass put as an argument won't work - the compiler catches that error for you.
If your intent is to call putBeeper put times then what you can do is decrement put after every invocation of putBeeper - put will eventually reach 0, at which point you've called putBeeper exactly put times. And since you're just learn to program in Java, I'll leave the actual implementation to you as an exercise. Good luck!
I am trying to write a recursive method which gives me the biggest-sum-pairs of integer (neighbors) within an array. It works perfectly, but only for the first run, because i cannot reset my static int maxSum; "counter" which I use to check, if the current sum is bigger than the biggest sum of previous runs. maybe you can give me an hint, its the first time I work with static counters in a recursion
static int maxSum = 0;
private static int getMaxPairSum(int[] workArray, int start, int end) {
while(start < end){
if (workArray[start] + workArray[start+1] > maxSum){
maxSum = workArray[start] + workArray[start+1];
return getMaxPairSum(workArray,start +1,end);
}
else return getMaxPairSum(workArray,start +1,end);
}
return maxSum;
}
A very simple way to do this could be:
Creating a temporary variable
Assigning the value of maxSum to the variable
Resetting maxSum
Returning the temporary variable
Would be like this:
while(start < end){
if (workArray[start] + workArray[start+1] > maxSum){
maxSum = workArray[start] + workArray[start+1];
return getMaxPairSum(workArray,start +1,end);
}
else return getMaxPairSum(workArray,start +1,end);
}
int tempMaxSum = maxSum;
maxSum = 0;
return tempMaxSum;
Hope this helped!
Thank you for your help! I decided to write a new code, it works perfectly and is recursive :D
private static int getMaxPairSum(int[] workArray, int start, int end) {
if (start==end)
return 0;
return Math.max((workArray[start] + workArray[start+1]), getMaxPairSum(workArray,start+1,end));
I feel like you’re still thinking too much in an iterative programming mindset. In recursion, you shouldn’t really need a global variable to keep track of changes. Instead, the changes should instead propagate either up (still very iterative thinking) or down (proper recursion!) your recursion stack, with the operation (in this case a comparison) being performed at each function call in that stack.
It should be the case that transitivity of the greater than operator applies here, so the max will be the largest regardless of when in the list it happens, so it doesn’t really matter when we find it. Try to come up with some concrete examples and walk through a few iterations of your method if that seems unclear.
An example of it being passed up your recursion stack would be adding a new argument to your method, such as “maxSum” and passing that through to each call, keeping track of the max at each call. Returning from this would still feel a bit "off", though, as you'd have the value of your result once you reach the end of the list, but then would still need to return it through all the recursive calls you made to the method until it got back to the first call.
The “most recursive” approach, here, would be to let your method work with a value that hasn't been determined yet but that it knows will be determined in the future, and to do that until it reaches the end case. Once it reaches the end, it will have gotten a concrete value, which allows an undetermined value for the previous call to now be determined, which allows an undetermined value for the call before that to be determined, etc., until the first call.
Here, the comparison would be Math.max(currentSum, nextSum), where currentSum = workArray[i] + workArray[i+1] and nextSum is the value returned by the next call to getMaxPairSum, which won’t actually be determined until you get to the end of the array (your terminating case for the recursion) which will return a value to the call before it, which in returns a value to the call before it, which returns a value to the call before it, and so on until you get back to the first call and so have your final value.
For a visualization based in data structures, this means that the calculations will propagate down the recursive function call stack until the very first call, which is the bottommost item in the stack.
I've come to wonder if there is a way to find out which method arguments are returned from.
If you have a few methods in a few classes, perhaps it's easier to figure out where the values come from to the parameter by looking at the method signature.
What if we have very complicated structure of classes? how can we efficiently figure it out? (other than using debugger)
I would appreciate your advice!
For example,
public class Recursion_fig18_9 {
//recursive declaration of method factorial
public static long factorial(long number){
long result = 1;
//iterative declaration of method factorial
for (long i = number; i >=1; i--){
result *= i;
}
return result;
}
//output factorials for values of 0 to 10
public static void main(String[] args) {
//calculate the factorials from 0 to 10
for (int counter =0; counter <= 10; counter ++){
System.out.printf("%d! = %d%n", counter, factorial(counter));
}
}
(Although this example is quite small structure of class,)
How can I figure out where "number" is returned from in the factorial method?
Using your debugger you can set a break point within the method. When that method breaks, you'll see a stack frame indicating where the call to the method came from and this will help you to trace back the method call to figure out how it was constructed.
Within your code example, place the breakpoint on the return statement so that you can examine the return value before it is returned.
Alternatively, you could use a logger to generate a log file and see how your code steps through it. You'd be able to back off the logging level after the fact so that you don't have to change code constantly. More on logging here
I am looking back at my old question and I am answering to my own question.
You can figure out easily without using debug which method calls the current method and passes the parameters by
selecting the current method
right mouse click
click Open Call Hierarchy (or Ctrl + Alt + H).
I am trying to learn recursion in Java and have an array that takes in continuous input until the Scanner reads in a 0.
From there I have a method that (attempts) to calculate the number of positive integers in the array using recursion. This is the first recursive function I have ever written and I keep getting a stackoverflow error.
I have read tutorials and I still can't wrap my head around the basic understanding of recursion.
public class reuncF {
private static int start = 0;
private static int end = 98;
public static void main(String[] args) {
input = input.nextDouble();
list[i] = numInput;
computeSumPositive(numList, count);
}
}
return positives += solve(numbers, count++);
}
}
You forgot to stop your recursion!
There has to be some case where computeSumPositive returns without calling itself again. Otherwise it'll just keep going forever, never getting back to you.
If you did it with a loop, the loop would look like this:
int positives = 0;
for (int i = 0; i < numList.length; ++i) {
if (numList[i] > 0) {
positives++;
}
}
To do that recursively, you just find out what are the variables used in the loop. They are i, numList and positives.
computeSumPositive(int i, double[] numList, int positives)
Then we take a look at what the loop does. First, it checks whether we went too far,
so our recursive function should do that too. It'll have to return instead of just falling through like the loop does. And obviously, it must return the result:
{
if (! (i < numList.length))
return positives;
The loop then does the test and maybe increments positives, so the recursive function should also do that:
if (numList[i] > 0) {
positives++;
}
At the end of the loop, i is updated:
i++;
The loop just starts over, but the recursive function will have to call itself. Of course, we want it to use the new value of i and positives, but fortunately we updated those, so now we can just do:
return computeSumPositives (i, numList, positives);
}
The tricky bit is that the values i, numList, and are local to each call. Each invocation of computeSumPositives can see only the arguments it were given. If it changes them, none of the other invocation can see that change.
EDIT: So if we, for reasons we can only speculate about, wanted desperately for computeSumPositive to take only 2 parameters, we would have to "split up" positives across each invocation. Each invocation knows whether or not its number was positive or not; all we have to do is add them. Then it looks like this:
computeSumPositive(int i, double[] numList)
{
if (! (i < numList.length))
return 0; // I didn't find any at index i
if (numList[i] > 0) {
// Theres one I found + however many my later
// invocations will find.
return 1 + computeSumPositive (i+1, numList);
} else {
// I didn't find any, but my later invocations might.
return computeSumPositive (i+1, numList);
}
}
I find it helpful, when dealing with recursion, to figure out the termination case first.
It looks like you are treating 'count' as an index. So you could check if your at the last index in the array, if so and if the value is positive return a 1, if the value is non-positive return a 0 - dont recurse anymore.
If your not at the last index, and the value is positive return a 1 + the recursive function call, or if the value is non-positive just continue to recurse.
This will still cause a stack overflow for large arrays.
The value of count++ is the same as the value of count; the program uses the value and then increments it. But the result is that computeSumPositive keeps calling itself with the same value of count, which leads to infinite recursion. Note that each time computeSumPositive calls another computeSumPositive, each call has its own copy of the parameters (like count) and the local variables; so incrementing one computeSumPositive's copy of count has no effect on the value of count used by other recursive calls.
Change count++ to count + 1, and also add a way to halt the recursion. (At some point, you will be calling computeSumPositive to look at zero integers, and at that point, it should just return 0 and not call itself. You need to think about: how do you test whether you've reached that point?)
I've been lurking here for a little while, but I've come into a problem that I can't solve in some Java programs I'm writing for an assignment. I bet they're not too difficult to figure out, but I'm just not getting it.
I've been getting errors along the lines of this:
RugbyTeamLadderEditor.java:125: cannot find symbol
symbol : method findAveragePoints(java.util.ArrayList<RugbyTeam>)
location: class RugbyTeamLadderEditor
double averagePointsToBePrinted = findAveragePoints(rugbyTeams);
I have three classes, and, from the class with the main method (RugbyTeamLadderEditor), I can call the constructor class, but not the other class which has some methods in it (Part1). Should I be doing something with packages? - all I know is that I didn't learn anything about packages in this introductory programming course that I'm doing, and I'm not sure how they would be received if I were to use them.
My code is a couple of hundred lines long, so I put them in pastebin - I hope I haven't transgressed any faux pas by doing this :/ Every class is in its own .java file.
http://pastebin.com/FrjYhR2f
Cheers!
EDIT: a few fragments of my code:
In RugbyTeamLadderEditor.java:
// if the identification number is equal to 5, then print out the average points of all of the teams in the ArrayList
else if (identificationNumber == 5)
{
double averagePointsToBePrinted = findAveragePoints(rugbyTeams);
}
In Part1.java:
/**
* This method takes a RugbyTeam ArrayList and returns a
* double that represents the average of the points of all
* of the rugby teams
*/
public static double findAveragePoints(ArrayList<RugbyTeam> rugbyTeams)
{
// If there are no objects in the ArrayList rugbyTeams, return 0
if (rugbyTeams.size() == 0)
return 0;
// Declare a variable that represents the addition of the points of each team;
// initialise it to 0
double totalPoints = 0;
// This is a code-cliche for traversing an ArrayList
for (int i = 0; i < rugbyTeams.size(); i++)
{
// Find then number of points a team has and add that number to totalPoints
RugbyTeam r = rugbyTeams.get(i);
totalPoints = totalPoints + r.getPoints();
}
// Declare a variable that represents the average of the points of each teams,
// i.e. the addition of the points of each team divided by the number of teams
// (i.e. the number of elements in the ArrayList); initialise it to 0
double averagePoints = totalPoints / rugbyTeams.size();
return averagePoints;
}
It's not quite finished yet - I still need to put a print statement in to print that double, but it's irrelevant for now because I can't actually get that double to take on a value.
Your are trying to call the method findAveragePoints. With the current implementation you say, that the method will be found in the class RugbyTeamLadderEditor. But the method is defined in the class Part1. So to make this work you prepend the call to the method with Part1. (since it is a static method) and the program should work.
EDIT
The code would basically look like this
double averagePointsToBePrinted = Part1.findAveragePoints(rugbyTeams);
Also every time you try to call a method that is defined in another class than the current you either have to provide an instance of this class or prepend the name of the class (like here Part1) to the method called.
As a side node you should change the name of your variable quitProgram. The name of the variable and its meaning contradict each other. So to make things more clear for anyone reading the code you should change either the name or the handling.