My code keeps returning false what am I doing wrong? This is the feedback I am getting.
checkTable() should only return false when it finds an incorrect entry.
Failed: java.lang.AssertionError: checkTable() should return false when entry at index 0 is not equal to 0.
/**
* This method checks if an array of ints contains a correctly calculated
* multiplication table.<br/>
* Precondition: multTable IS NOT null. (PRECONDITIONS SPECIFY RESPONSIBILITIES
* ON A METHOD'S CALLER; YOU SHOULD ASSUME THIS IS TRUE.)
*
* #param constant
* Value used to check the multiplication table.
* #param multTable
* Table to be checked.
* #return True if every entry in the array stores the value of {#code constant}
* * the index for that entry; or false if at least one entry is
* incorrect.
*/
public static boolean checkTable(int constant, int[] multTable) {
int i=0;
for(i=0;i<multTable.length;i++){
int mult = constant*i;
if(mult==multTable[i]) {
return true;
}
}
return false;
}
Right now you are immediately returning true if only one entry in the Array is valid:
if(mult==multTable[i]) {
return true;
}
It needs to be the other way around:
for(i=0;i<multTable.length;i++){
int mult = constant*i;
if(mult!=multTable[i]) {
return false;
}
}
return true;
Just step through the code, line by line. Let's say the constant is '5', and the input is new int[] {0, 15, 38}; which is clearly not a multiplication table.
int i = 0;: i now exists. The value of i is now 0.
for (int i = 0; i < multTable.length; i++) { we're going to loop 3 times. We enter the loop with the first value (0).
int mult = constant * i;: mult now exists. The value of mult is 0 (because 5*0 is 0).
if (mult == multTable[i]) return true;: mult is 0; the first item in our example multTable input is 0. Therefore the if triggers and the entire method returns, with value true. The remaining elements aren't checked at all.
The fix is obviously NOT to return when the first element is correct. When you hit a 'mistake' you know immediately that the answer to the question "Is this a valid multiplication table" is false. But when you hit a correct entry that doesn't mean you know the answer. You'd have to keep going.
This smells of homework so I'll let you do the honours of figuring out what that means and how you can fix your code.
NB: This is how you solve problems with code: You reason through it. You check what the code actually does (using a debugger, or if that's a bridge too far to learn for now, add a lot of System.out.println statements). The point where your code doesn't match what you thought it should do is the point where you figured out the bug.
Related
I'm trying to solve the problem of "count ways to reach the nth step in a staircase" with recursion. When given a number of stairs to climb, I have to calculate the number of ways to climb taking either 1 or 2 steps at a time. For example, if there are 4 stairs, we would return 5 since we would have:
* 1 1 1 1
* 1 1 2
* 1 2 1
* 2 1 1
* 2 2
My code is currently throwing a stack overflow exception:
public static int countWaysToClimb(int stairs) {
return countWaysToClimbHelper(stairs, 0, 0);
}
public static int countWaysToClimbHelper(int sumNeeded, int currentSum, int possibleCombos) {
// base - we will reach this base multiple times
if (sumNeeded == currentSum) {
possibleCombos++;
// if we already found a combo, we need to reset the sum
countWaysToClimbHelper(sumNeeded,0,possibleCombos);
}
else if (currentSum > sumNeeded) {
return 0;
}
// recurse - add 1 and then add 2
countWaysToClimbHelper(sumNeeded,currentSum+1,possibleCombos);
countWaysToClimbHelper(sumNeeded,currentSum+2,possibleCombos);
return possibleCombos;
}
Thank you!
There are some issues in your code:
Base case (condition that terminates the recursion) is incorrect. Every branch of recursive calls spawn new branches when it hits the condition if (sumNeeded == currentSum) is meat instead of returning the number of combinations. You created an infinite recursion that inevitably leads to a StackOverflowError. You have to place a return statement inside the curly braces after the first if in your code. And comment out the first recursive call (with 0 sum passed as an argument) you'll face the second problem: for any input, your code will yield 0.
Results returned by recursive calls of your method countWaysToClimbHelper() are omitted. Variable possibleCombos isn't affected by these calls. Each method call allocates its own copy of this variable possibleCombos on the stack (a memory aria where JVM stores data for each method call), and their values are not related anyhow.
you actually don't need to pass the number of combinations as a parameter, instead you have to return it.
Before moving further, let me recap the basics of recursion.
Every recursive method should contain two parts:
base case - that represents a simple edge-case for which the outcome is known in advance. For this problem, there are two edge-cases:
sumNeeded == currentSum - the return value is 1, i.e. one combination was found;
sumNeeded > currentSum - the return value is 0.
recursive case - a part of a solution where recursive calls a made and when the main logic resides. In your recursive case you need to accumulate the value of the number of combination, which will be the sum of values returned be two branches of execution: take 1 step or 2 steps.
So the fixed code might look like that:
public static int countWaysToClimb(int stairs) {
return countWaysToClimbHelper(stairs, 0);
}
public static int countWaysToClimbHelper(int sumNeeded, int currentSum) {
// base - we will reach this base multiple times
if (sumNeeded == currentSum) {
return 1;
} else if (currentSum > sumNeeded) {
return 0;
}
// recurse - add 1 and then add 2
int possibleCombos = 0;
possibleCombos += countWaysToClimbHelper(sumNeeded,currentSum + 1);
possibleCombos += countWaysToClimbHelper(sumNeeded,currentSum + 2);
return possibleCombos;
}
Note:
This code could be enhanced further. The whole logic can be implemented inside the countWaysToClimb() without using a helper-method. For that, instead of tracking the currentSum you need to subtract the number of steps from the sumNeeded when the method is called recursively.
I want to ask about the following code ,specifically for the line 7.
This is an exercise with CodingBat AP-1 > scoresIncreasing, and it reads like this
"Given an array of scores, return true if each score is equal or greater than the one before. The array will be length 2 or more."
The following solution is correct but if I change the line:7 from "return false;" to "score=false;" the method returns another incorrect result.
Please tell me what is the difference between "return false;" and "score=false;" and why is this happening?
public boolean scoresIncreasing(int[] scores) {
boolean score = false;
for(int i = 0; i < scores.length-1; i++){
if(scores[i+1] >= scores[i]){
score = true;
}else {
return false;
}
}
return score;
}
Thank you in advance for your answer.
It's just because with "return false;" in the 7th line you are exiting method early, with correct result, as algorithm implies.
If you are just assigning false value to score, you continue looping, so, result becoome invalid in some cases (just because further you may re-assign score with true).
Well because return false stops the execution of the for loop and returns the value to where the scoresIncreasing function was called from as soon as it counters a value of score which is less than value of previous score.
Whereas when you use score=false the for loops runs through complete array and then returns true or false only on the condition of whether the last elements of array is greater or smaller than it's previous value
I am trying to create a single for-loop that uses the variable 'lapTime' to store the current lapTime for hypothetical skiers. The skiers are to complete 5 laps and each lap there is a slow rate of 10%. The method I am writing should allow the user to input their lap number and my for loop should predict the time that the skier will finish their lap.
slowRate Formula:
nextLapTime = previous lap time + (previous lap time * slowrate);
I tried using "if-else" statements in the for loop to force it to return different values that are dependent on the users lapNumber input, but that only breaks the for-loop (dead code error).
Currently, the for-loop only returns one value for each time it iterates through the loop -- 11 seconds. I've tried doing: lapTime = lapTime + (lapTime * slowRate), but that returns 16.(numbers) for whatever weird reason. Even though lapTime should be set equal to firstLapTime which == 10. The code I have provided below returns a value of 15 -- idk why..
The For-Loop:
public double getLapTime(double firstLapTime, double slowRate, int lapNumber)
double lapTime;
lapTime = firstLapTime;
for (lapNumber=1; lapNumber<=5; lapNumber ++) {
lapTime = lapTime + (firstLapTime * slowRate);
}
return lapTime;
}
Here are the test methods that I am trying to debug --
1)
public void testShouldHaveSecondLapOf11Seconds() {
// Act: call our method with proper parameter value for our test
double actualResult = theCalculator.getLapTime(10, .1, 2);
// Assert: assert that our expected value is equal to the actual result
assertEquals(11.0, actualResult, 0.001);
2)
public void testShouldHaveThirdLapOf12Point1Seconds() {
// Act: call our method with proper parameter value for our test
double actualResult = theCalculator.getLapTime(10, .1, 3);
// Assert: assert that our expected value is equal to the actual result
assertEquals(12.1, actualResult, 0.001);
}
I am expecting to receive the values as shown in the JUnit tests, and somehow
the logic in my for-loop is not returning the lapTimes that it should. It returns only one number for each iteration of the loop.
PS.. this is one of my first posts, so sorry in advance for any formatting issues. I'll try my best to improve on that. Thanks!
I think your problem is in the for loop itself. because even though you call getLapTime() method and pass 3 as the lapNumber, you still assign the value 1 to it in your for loop. So, instead that your lapNumber is equal to 3, it's actually equal to 1.
for (lapNumber=1 /* your chaning the value of lapNumber here to 1 */; lapNumber<=5; lapNumber ++) {
lapTime = lapTime + (firstLapTime * slowRate);
}
you can try
for (int i = lapNumber; i <= 5; i++) {
lapTime = lapTime + (firstLapTime * slowRate);
}
I believe there are two mistakes in your code.
The first one is in the way you made your for loop. I believe you want to compute the next lap's time at each iteration. One iteration will give you the 2nd lap, 2 iterations will yield the 3rd lap time etc. This is not what you are currently doing as you are always computing the 5th lap time.
Then, by looking at the answer expected for the second lap, I think the slowdown is relative to the last lap performed, not the first one. Otherwise you wouldn't need a for loop to compute the nth lap time, you would just need to compute the absolute slowdown once, multiply that by the number of laps you want and add it to the first lap's time. The weird reason why it was not working before is because of the faulty for loop iteration problem you have.
I would suggest this for loop:
for (int id = 1; i < lapNumber; i++) {
lapTime = lapTime + (lapTime * slowRate);
}
I have an update method which gets called every time the screen refreshes itself.
Inside this method I check the value of about about 50 objects to be zero. If all the values are zero I return a true else false is returned.
This is how I have implemented and want to know if there is a better way to do it.
public boolean update()
{
float totalVel = 0;
for(int i=0; i< this.numOfObjects; i++)
{
totalVel += BagOfWordsAverage[i];
}
if(totalVel == 0)
return true;
return false;
}
Depending on the boolean value returned, the caller of the udpate function allows certain inputs from the user. So if False is returned, the user cannot tap on the screen but in the case of true the user is allowed to do whatever she wants.
BagOfWordsAverage is a float array. I simply add the values of the entire array and check if the total is 0. No item in the array can take a negative value.
Is there a better way to achieve what I want to achieve? The challenge is that if the number of objects increased to 5000 will my method scale? Since this is for an App, speed is very important.
If all the values are zero I return a true else false is returned.
So, as soon you see a non-zero value, you can return false immediately.
If you get out of the loop,
that must mean that everything was zero, and you can return true.
public boolean update()
{
for(int i=0; i< this.numOfObjects; i++)
{
if (BagOfWordsAverage[i] > 0) return false;
}
return true;
}
Btw a better way to iterate over arrays in Java:
public boolean update()
{
for (float value : BagOfWordsAverage)
{
if (value > 0) return false;
}
return true;
}
Also, the naming convention in Java is camelCase for variable names,
so I suggest to rename BagOfWordsAverage to bagOfWordsAverage.
An efficient solution is not to loop at all. You can have a map for every index with a value more than zero. If the map's size is 0, then you know that the array's total is zero.
You didn't post your code structure, but something like this might give you an idea:
Map<Integer, Boolean> moreThanZero = new HashMap<>();
public void someActionOnArray(int index) {
/*
do some action
*/
float value = bagOfWordsAverage[index];
if (value > 0) {
moreThanZero.put(index, true);
}
if (value == 0) {
if (moreThanZero.containsKey(index)) {
moreThanZero.remove(index);
}
}
}
public boolean update() {
return (moreThanZero.size() == 0);
}
Every method that modify the array should check the modified value at the current index. If it's more than zero, mark the index on the map. If it's less than zero, remove it if it exist.
This might cost you some memory if the size of indices with value more than zero is large, but you'll gain speed as you don't have to loop every time you refresh.
One way that you could slightly improve the speed of your method would be to check each value and see if it is zero, and if it isn't, return false immediately. If you make it through the loop without finding any values other than zero, you can return true.
public boolean update()
{
for(int i=0; i< this.numOfObjects; i++)
{
if (BagOfWordsAverage[i] != 0)
{
return false;
}
}
return true;
}
Note that while the actual average case run-time of your function will improve with this change (i.e if there is a nonzero in the middle of the array, your run-time will be O(n/2) rather than O(n)), big-O analysis typically omits all but the highest-order function, and considers things like O(3n), O(n/2) to be simplified to simply O(n), as they are run on linear time.
As far as your question regarding an array of 5000 items, average case would take half the time of your original function, but in the worst case, the speed would be the same. If there are no assumptions we can make about where the possible location of these nonzero numbers would be, there is no other option than to check each index of the array individually.
Hopefully this helps.
You want to return false as soon as you get a non-zero value right? Do something like:
for(int i = 0; i < foo.length; i++) {
if (foo[i] > 0) {
return false;
}
}
return true;
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am preparing for an exam next week, and I decided to look for some exam questions online for better preparation.
I came across this question and the answer is c. But I really want to know how or the step by step process to answer to answer a question like this. The part where I got stuck is trying to logically understand how a int m = mystery(n); How can a number equal a method? Whenever I get to a question like this is their anything important I should breakdown first?
private int[] myStuff;
/** Precondition : myStuff contains int values in no particular order.
/*/
public int mystery(int num)
{
for (int k = myStuff.length - 1; k >= 0; k--)
{
if (myStuff[k] < num)
{
return k;
}
}
return -1;
}
Which of the following best describes the contents of myStuff after the
following statement has been executed?
int m = mystery(n);
(a) All values in positions 0 through m are less than n.
(b) All values in positions m+1 through myStuff.length-1 are
less than n.
(c) All values in positions m+1 through myStuff.length-1 are
greater than or equal to n.
(d) The smallest value is at position m.
(e) The largest value that is smaller than n is at position m.
See this page to understand a method syntax
http://www.tutorialspoint.com/java/java_methods.htm
int m = mystery(n); means this method going to return int value and you are assigning that value to a int variable m. So your final result is m. the loop will run from the array's end position to 0. loop will break down when array's current position value is less than your parameter n. on that point it will return the loop's current position. s o now m=current loop position. If all the values of the loop is greater than n it will return -1 because if condition always fails.
Place the sample code into a Java IDE such as Eclipse, Netbeans or IntelliJ and then step through the code in the debugger in one of those environments.
Given that you are starting out I will give you the remainder of the code that you need to make this compile and run
public class MysteriousAlright {
private int[] myStuff;
public int mystery(int num)
{
for (int k = myStuff.length - 1; k >= 0; k--) {
if (myStuff[k] < num) {
return k;
}
}
return -1;
}
public static void main(String[] args) {
MysteriousAlright ma = new MysteriousAlright();
ma.setMyStuff(new int[] {4,5,6,7});
int m = ma.mystery(5);
System.out.println("I called ma.mystery(5) and now m is set to " + m);
m = ma.mystery(3);
System.out.println("I called ma.mystery(3) and now m is set to " + m);
m = ma.mystery(12);
System.out.println("I called ma.mystery(12) and now m is set to " + m);
}
public void setMyStuff(int[] myStuff) {
this.myStuff = myStuff;
}
}
You then need to learn how to use the debugger and/or write simple Unit Tests.
Stepping through the code a line at a time and watching the values of the variables change will help you in this learning context.
Here are two strategies that you can use to breakdown nonsense code like that which you have sadly encountered in this "educational" context.
Black Box examination Strategy
Temporarily ignore the logic in the mystery function, we treat the function as a black box that we cannot see into.
Look at what data gets passed in, what data is returned.
So for the member function called mystery we have
What goes in? : int num
What gets returned : an int, so a whole number.
There are two places where data is returned.
Sometimes it returns k
Sometimes it returns -1
Now we move on.
White Box examination Strategy
As the code is poorly written, a black box examination is insufficient to interpret its purpose.
A white box reading takes examines the member function's internal logic (In this case, pretty much the for loop)
The for loop visits every element in the array called myStuff, starting at the end of the array
k is the number that tracks the position of the visited element of the array. (Note we count down from the end of the array to 0)
If the number stored at the visited element is less than num (which is passed in) then return the position of that element..
If none of elements of the array are less than num then return -1
So mystery reports on the first position of the element in the array (starting from the end of the array) where num is bigger than that element.
do you understand what a method is ?
this is pretty basic, the method mystery receives an int as a parameter and returns an int when you call it.
meaning, the variable m will be assigned the value that returns from the method mystery after you call it with n which is an int of some value.
"The part where I got stuck is trying to logically understand how a int m = mystery(n); How can a number equal a method?"
A method may or may not return a value. One that doesn't return a value has a return type of void. A method can return a primitive value (like in your case int) or an object of any class. The name of the return type can be any of the eight primitive types defined in Java, the name of any class, or an interface.
If a method doesn't return a value, you can't assign the result of that method to a variable.
If a method returns a value, the calling method may or may not bother to store the returned value from a method in a variable.