Program constantly says missing return statement - java

My program is supposed to be passed 2 array-lists, arrivals and duration, and should return the number of events that can basically take place without overlap. The last thing I did was add the final else if statement to count the last arrival as an event that could take place. However, my code constantly gives a no return statement error although there is a return statement.
class Results {
public static int maxEvents(List<Integer> arrival,List<Integer> duration) {
int counter = 0;
for (int i = 0; i < arrival.size(); i++) {
if (arrival.get(i) + duration.get(i) <= arrival.get(i+1)) {
counter++;
} else if (arrival.get(i)==arrival.get(i+1)) {
counter++;
i++;
} else if (i == arrival.size()-1) {
counter++;
}
return counter;
}
}
}

The return statement which you have written lies within for loop that is incorrect.
please follow below code
class Results {
public static int maxEvents(List<Integer> arrival,List<Integer> duration) {
int counter = 0;
for (int i = 0; i < arrival.size(); i++) {
if (arrival.get(i) + duration.get(i) <= arrival.get(i+1)) {
counter++;
} else if (arrival.get(i)==arrival.get(i+1)) {
counter++;
i++;
} else if (i == arrival.size()-1) {
counter++;
}
}
return counter;
}
}

The Java compiler requires that all methods with a non-void return type either:
Return a value (or throw) on all paths
Definitely don't return a value (e.g. if they contain an infinite loop).
It determines this by looking at the statements in your method to see if they "complete normally". This is a bit of a funny term, but it basically means that execution would move onto the next statement (or the method would finish executing if it is the last statement in the method).
In this case, it looks at the loop:
for (int i = 0; i < arrival.size(); i++) {
// ...
return counter;
}
And it finds that:
The for loop body completes abruptly (it always returns a value)
The for loop might be able to complete normally, because i < arrival.size() isn't a constant (*).
As such, it looks after the for loop to make sure that all following paths return a value (or throw). But this cannot be the case, because there are no statements after the for loop. As such, a compile-time error results.
The easiest way to satisfy the compiler is to put another return after the for loop:
for (int i = 0; i < arrival.size(); i++) {
// ...
return counter;
}
return /* some int */;
Or make the guard expression constant true (or omit it):
for (int i = 0; true; i++) {
// ...
return counter;
}
However, your loop body always returns if entered; so it is basically if (0 < arrival.size()) rather than a loop. And it would only ever return 0 or 1, because counter is incremented at most once.
This is presumably a logical error: the return shouldn't be inside the loop, allowing you to count the number of items in the list which meet the condition:
for (int i = 0; i < arrival.size(); i++) {
// ...
}
return counter;
(*) The compiler doesn't look any deeper than the fact it's not a constant equal to true. For example, i <= Integer.MAX_VALUE isn't constant, and thus is considered to allow normal completion, but it is clearly always true.

Related

Why return should be last line of my method? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 days ago.
Improve this question
I am trying to solve this problem:
Solve for square root.
And this is my code:
public class Solution {
public int sqrt(int A) {
for(int i=0;i<A;i++)
{
if(A%i==i)
{
return i;
}
}
for(int i=A;i>0;i--)
{
for(int j=0;j<A;j++)
{
if(A%j==j)
{
return j;
}
}
}
}
}
But after I try to run it on Interview Bit it shows an error:
./Solution.java:23: error: missing return statement
}
^
1 error
Now I am not able to even run my code.
Your method should have a return, that's the rules. It's not necessarily in the last line, but there should never be a case when there is no return. With your custom algorithm, your return is always conditional and the compiler will not know in advance whether those conditions will ever be true.
So, the problem is like this:
Lets assume that A is a negative number (e.g. -1):
The 1st loop body will never be executed since i (0) is greater then A (-1)
for(int i=0;i<A;i++)
The 2nd loop body will never be executed since i (-1) is smaller then 0.
for(int i=A;i>0;i--)
therefore - we arrived to the end of the function and there is nothing to return even that the function declared as returning int.
Basically - all paths must have return statement (unless the function is void - and in such a case the return statement can be implicit)
If you have declared a method with expects a return type then you must have to take care of all the scenarios of executing all the blocks in that method. Whatever is the code block the method is executing it must return something of the required type.
Find the missing block in your code below :
public class Solution {
public int sqrt(int A) {
for(int i=0;i<A;i++)
{
if(A%i==i)
{
return i; // returning an int here which is correct
} // what if the the 'if' condition is not met. Add a return type for else
}
for(int i=A;i>0;i--)
{
for(int j=0;j<A;j++)
{
if(A%j==j)
{
return j;
} // same what if the condition is not met add a return in 'else' if required.
}
} // if you are not adding any return in the else block. which is not required in your current program then just add a default return to your function.
}
}
For some more information check this
Although you do have two return statements, the compiler is specifying that it still does not have anything to return if both of your conditions aren't met (false).
So to understand, you would have to ask yourself: What would happen if both of these conditions are false? (Conditions being if (A % i == i) and if (A % j == j))
Solution:
public int sqrt(int A) {
for (int i = 0; i < A; i++) {
if (A % i == i) {
return i;
}
}
for (int i = A; i > 0; i--) {
for (int j = 0; j < A; j++) {
if (A % j == j) {
return j;
}
}
}
return -1; //-1 or 0 is widely returned by default to represent a failed function
}
So basically, when creating a method which is expecting something to be returned, you have to return it outside any conditional statements.
Your method Signature is :
Integer sqrt(int A)
Which says that your method body must return an Integer.
Now, in your code ,you are returning value but when certain condition is true.What if that condition is not true.Compiler is smart enough to find that ,in that case,there is no return value,hence the error.
Return should be the last line of your method not the class. As you have declare that method as 'int type', so you should have returned an int value. Compiler can't identify whether that 'if condition' reaches true in all inputs. so you should place a return 0 at the end of the method.
You're not assuring a return value in every state of your method. Besides that, your code doesn't makes sense.
1.You're dividing by zero in the first if loop (don't do that, it's forbidden)
2.The condition i > 0 in the second for loop will always be false.
At the end it should look something like this
public int sqrt(int A) {
for () {
if () {
return i;
}
}
for () {
for () {
if () {
return j;
}
}
}
return 0;
}
If the only thing you want to do is to square a number, use the Math.pow method, don't reinvent the wheel!
int i = 2;
int square = Math.pow(i, 2);

How to create the FizzBuzz using loops in JAVA

I'm writing this problem for school and I have some issues with it. I can't get "printFizzBuzz" to actually go up and calculate the wrapper function "FizzBuzz". I am required to use loops and was attempting to use a FOR loop. Beginner programmer here so no, I haven't used loops much at all. Any tips or pointers? ;)
The instructions are as follows.
public static String FizzBuzz(int number)
{
if( (number%3==0) && (number%5==0)) {
return "FizzBuzz";
}
else if( number%3 == 0 ) {
return "Fizz";
} else if( number%5 == 0 ) {
return "Buzz";
} else {
return ""+number;
}
}
/*
* use a for loop to print the appropriate FizzBuzz values (feel free to
* call the provided FizzBuzz function) for values from from to to,
* including both of those values. Each value should be printed in a separate line.
*/
public static void printFizzBuzz(int from, int to, PrintStream out)
{
for (int i = 1; i <= to; ++i){
FizzBuzz(++i);
}
}
Take a look at the FizzBuzz function:
public static String FizzBuzz(int number)
public static STRING tells you that this function returns a string.
Each time you write
FizzBuzz(++i);
imagine this to be a string like "Fizz"
So in your program what you really wrote is
for (int i = 1; i <= to; ++i){
"Fizz";
}
That doesn't look good right? You actually need to assign this string to something, or do some stuff with it. For example:
for (int i = 1; i <= to; ++i){
String a = "Fizz";
System.out.println(a);
}
Better, this is printing it to the standard output! However your function has already one PrintStream out parameter that you can use to print!
for (int i = 1; i <= to; ++i){
String a = FizzBuzz(i++);
out.println(a);
}
Now let's take a look at the for loop: it creates a variable i that starts from 1 (int i = 1), checks the condition ( i <= to) and if the condition is satisfied it executes the body of the loop. After that it increments i by 1 (++i).
So the first 3 rounds of the loop will be unrolled like this:
int i = 1;
if(i<=to){
String a = FizzBuzz(i++);
out.println(a);
}
++i; //i = 3;
if(i<=to){
String a = FizzBuzz(i++);
out.println(a);
}
++i; //i = 5;
if(i<=to){
String a = FizzBuzz(i++);
out.println(a);
}
++i; //i = 7;
Looks like we still have a problem here. Why is i 3, then 5 and then 7? What happened to 2,4,6? The problem is that you are also incrementing i by 1 when calling FizzBuzz (FizzBuzz(i++)).
This is wrong, the loop is already incrementing i for you by 1, if you increment i by 1 more, it will be incremented by 2 each round.
I'll leave the final fix to you.

How do you return a zero if there is nothing in the grid where you checked?

To start things off, I am making a game. You fight on a 3x3 Grid (using a 2 Dimensional-Array), and if the "Lane#" (Lane# = Row + Col) ahead of you is blank then you get a -15% Damage Reduction, and this stacks for every blank lane.
This means if you are on [0][0] then you are in Lane# 0, and therefore, cannot possibly have anyone ahead of you, and you will always take 100% of Damage (this is of course without defense and yadda yadda else that modifies)
And if you are on [2][2] then you are in Lane# 4, and if every lane ahead of you has atleast one space in it taken, then you will take 15*4 = 60, 100-60 = 40% of actual damage.
Now that that is out of the way. I am having difficulty returning 0... I keep getting an Error that says that you cannot return a Void value...
'cannot return a value from method whose result type is void'
public Blanks(int l) { //l = Lane
int x = 0; //The Return
for (int i = 0; i < 6; i++) //The loop
if (l=0){ //Here I keep getting an error saying 'incompatible types'
x = 0;
return x; //Here is the 'cannot return a void value' error
break;
}
if (l>=1){
x++;
}
if (l>=2){
x++;
}
if (l>=3){
x++;
}
if (l>=4){
x++;
}
return x; //for some odd reason, this is also a void value
}
}
I still have yet to add the Checking the Array / Grid part as I am stumped about that one as well.. but another problem, another question.. the actual array itself..
you should modify the method header to public int Blanks(int l) {
and you should remove break; keyword because you return method value before it and will be unreached statement.
In order to return an integer value you have to mention a return type in the method. Also, in the first if statement you have used assignment operator instead of comparing.
Also why you have used break after return. I think you have to do first break and then return in the end.
One more thing to add. Your for loop should contain braces. Only the first if statement will get executed according to your code.
public int Blanks(int l) { //l = Lane
int x = 0; //The Return
for (int i = 0; i < 6; i++) //The loop
if (l==0){ //Here I keep getting an error saying 'incompatible types'
x = 0;
break;
}
if (l>=1){
x++;
}
if (l>=2){
x++;
}
if (l>=3){
x++;
}
if (l>=4){
x++;
}
return x; //for some odd reason, this is also a void value
}
}
I haven't stepped into your logic. Comment if you face any problem after this.
I don't understand why you are using the for loop here, but this is a way to do it:
public int Blanks(int l) {
int x = 0;
for (int i = 0; i < 6; i++)
if (l==0){
x = 0;
}else {
x++;
}
return x;
}
But in case that l==0 your method will return 5;
If you want to return 0 or 1 then you need to remove the for loop
public int Blanks(int l) {
if (l==0) return 0;
else return 1;
}
And the method with true-false:
public boolean Blanks(int l) {
if (l==0) return false;
else return true;
}

Cannot print out the right sum

I have assigned a letter grade to each student based on his/her grade. And I want to count the total number of students for each letter grade. But for some reasons, the result turns total wrong. Can anyone tell me what parts I did wrong? Thank you!
String letter ="A";
int letterA=0;
int letterB=0;
int letterC=0;
int letterD=0;
int letterF=0;
int a=0;
int b=0;
int c=0;
int d=0;
int f=0;
for (int row=0;row<100;row++){ //the outer loop, have 100 rows to go through
for ( int column=0;column<words.length;column++) {
if(words[column].equals(table[row][column])){ // compare two arrays
count++; }// add the score for each student if he/she is right
}
if (count >=18)
letter=("A");
if(count>=16 && count<18)
letter=("B");
if(count>=14 && count<16)
letter=("C");
if(count>=12 && count<14)
letter=("D");
if(count<12)
letter=("F");
System.out.println("Student Grade: "+letter+"\t");
count=0; // make sure the count will go back to 0, and run the loop again
if (letter.equals("A"))
letterA++;
a+=letterA;}
if (letter.equals("B"))
letterB++;
b+=letterB;
if (letter.equals("C"))
letterC++;
c+=letterC;
if (letter.equals("D"))
letterD++;
d+=letterD;
if (letter.equals("F"))
letterF++;
f+=letterF;
System.out.print("Question A "+a);
System.out.print("Question B "+b);
System.out.print("Question C "+c);
System.out.print("Question D "+d);
System.out.print("Question F "+f);
}
Always use braces, even for single statements:
if (letter.equals("A"))
letterA++;
a+=letterA;}
if (letter.equals("B"))
letterB++;
b+=letterB;
if (letter.equals("C"))
letterC++;
c+=letterC;
if (letter.equals("D"))
letterD++;
d+=letterD;
if (letter.equals("F"))
letterF++;
f+=letterF;
Should always be:
if ("A".equals(letter)) { letterA++; }
else if ("B".equals(letter)) { letterB++; }
else if ("C".equals(letter)) { letterC++; }
else if ("D".equals(letter)) { letterD++; }
else if ("F".equals(letter)) { letterF++; }
else { throw new RuntimeException("Invalid Letter " + letter); }
Use single line statements if you want them visually compact, but
still use the braces as they guarantee the intent of what is to be
done in a given block, they also act as documentation of that intent
for people in the future ( people includes you ) to know what is going
on.
I see no valid reason for the single letter variables they are never used and I do not understand why they are there?
General Critique:
Always use braces:
Leaving out braces means only the first statement after the if is executed when the if matches, the next line(s) are always executed.
if (letter.equals("A"))
letterA++;
a+=letterA;
is actually
if (letter.equals("A")) { letterA++; }
a+=letterA;
Which means that line outside the braces will always get executed no matter what the expression inside the if test evaluates to. The indention of the second line is conflating that statement as part of the if block and it is not.
There is absolutely nothing to gain by leaving out braces and
everything to lose.
Neat code is easy to read and maintain and shows you care:
Always format your code consistently and not so densely so you can tell what is going on and what was wrong with the braces missing version.
Look at the best advertising it has plenty of white space, clean formatted code should have plenty of consistent white space as well so that our brains can quickly pattern match and scan for relevant things like matching pairs of braces.
Clean formatted code is just a keystroke away in all IDEs worth using.
Clean code shows you care about what you are doing and makes your question more appealing, which means others will care about their answer just as much.
Clean code earns you respect from your peers that know what they are looking at and sets you apart from those that do not care or know what they are looking at.
Most Importantly Clean Code is easier to reason about and has less
bugs, no subtle bugs and is orders of magnitude easier to maintain.
Always cover all the conditions:
Always use if/else if/else with mutually exclusive tests.
If all the if clauses are mutually exclusive and you match the first one, all the rest are still evaluated for no reason with the if/if/if/if structure. if/else if/else if/else if/else only evaluates until something matches or nothing matches.
Without else you do not cover all possible cases that do not match, which is usually and error that will just occur silently without the else.
Do not just cover the happy path, cover the exceptional path, but do it in the least defensive manner possible.
Explicit is always better than Implicit!
Avoid == null checks; avoid null completely:
Always compare literals to variables with .equals() to avoid possible NullPointerExceptions.
Avoid using null references completely, it is possible in every case, even the cases that it seems like a legitimate reason.
If Tony Hoare, the inventor of them thinks it is a mistake
who is to argue.
Always Name your variables descriptively!
I am not sure what letterA is supposed to represent anymore than what a is supposed to represent. So no one can tell you if these are correct because no one knows for sure what they represent semantically.
No Unnamed Numerical Constants ( Magic Numbers ):
final int A_GRADE = 18;
final int B_GRADE = 16;
final int C_GRADE = 14;
final int D_GRADE = 12;
Given the way they are used the names arguably could be even better
like MINIMUM_A_GRADE, but that is opinion based, the lesson is avoid
magic numbers.
Do range checks in the same direction:
Do range checks in the same direction so that the variable is visually in the middle of the comparison.
This makes it harder to break the logic later on and is self documenting that it is a range check.
if (count >= A_GRADE) { /* omitted */ }
else if (B_GRADE <= count && count < A_GRADE) { /* omitted */ }
else if (C_GRADE <= count && count < B_GRADE) { /* omitted */ }
else if (D_GRADE <= count && count < C_GRADE) { /* omitted */ }
else /* isF */ { /* omitted */ }
Which one is easier to reason about and maintain?
Do not hesitate to have many small methods if they make the code more self documenting:
private static boolean isA(final int count) { return count >= A_GRADE; }
private static boolean isB(final int count) { return B_GRADE <= count && count < A_GRADE; }
private static boolean isC(final int count) { return C_GRADE <= count && count < B_GRADE; }
private static boolean isD(final int count) { return D_GRADE <= count && count < C_GRADE; }
then you will have the following:
if (isA(count)) { /* omitted */ }
else if (isB(count)) { /* omitted */ }
else if (isC(count)) { /* omitted */ }
else if (isD(count)) { /* omitted */ }
else /* isF */ { /* omitted */ }
Which one is more obvious and self documenting, thus more
maintainable?
DRY - Don't Repeat Yourself:
Logically if (count >= A_GRADE) { letter = "A";} is exactly the same as if ("A".equals(letter)) { /* do stuff */ } so this is duplicated logic.
Instead of assigning a letter than checking that again, just put the logic in the original check.
if (count >= A_GRADE) { /* do stuff */ }
else if (B_GRADE <= count && count < A_GRADE) { /* do stuff */ }
else if (C_GRADE <= count && count < B_GRADE) { /* do stuff */ }
else if (D_GRADE <= count && count < C_GRADE) { /* do stuff */ }
else { /* omitted */ }
I see no valid reason for the single letter variables they are never used and I do not understand why they are there?
Duplicate logic means multiple places to have errors and multiple
places to edit to fix bugs, save yourself time and effort and follow
the DRY principle.
Move large logic blocks to method calls:
When do stuff is more than a few lines, refactor it to a method call.
if (count >= A_GRADE) { recordMarkA(); }
else if (B_GRADE <= count && count < A_GRADE) { recordMarkB(); }
else if (C_GRADE <= count && count < B_GRADE) { recordMarkC(); }
else if (D_GRADE <= count && count < C_GRADE) { recordMarkD(); }
else { recordMarkF(); }
More small methods with descriptive names is always better than large
monolithic blocks of inline code.
This question shows substantial effort and a genuine desire to learn:
So I crafted up what I would want a complete solution ( provided the partial/incomplete code ) to look like.
Q34081279.java
public class Q34081279
{
final static int A_GRADE = 18;
final static int B_GRADE = 16;
final static int C_GRADE = 14;
final static int D_GRADE = 12;
public static void main(final String[] args)
{
final String[] words = new String[]{}; /* this is just a placeholer, not provided in question */
final String[][] table = new String[][]{}; /* this is just a placehoder, not provided in question */
int markA = 0;
int markB = 0;
int markC = 0;
int markD = 0;
int markF = 0;
for (int row = 0; row < 100; row++)
{
int count = 0;
for (int column = 0; column < words.length; column++)
{
if (words[column].equals(table[row][column])) { count++; }
}
if (count >= A_GRADE) { System.out.format("%d = A", count); }
else if (B_GRADE <= count && count < A_GRADE) { System.out.format("%d = B", count); }
else if (C_GRADE <= count && count < B_GRADE) { System.out.format("%d = C", count); }
else if (D_GRADE <= count && count < C_GRADE) { System.out.format("%d = D", count); }
else { System.out.format("%d = F", count); }
System.out.println();
}
System.out.println(String.format("Question A %d", markA));
System.out.println(String.format("Question B %d", markB));
System.out.println(String.format("Question C %d", markC));
System.out.println(String.format("Question D %d", markD));
System.out.println(String.format("Question F %d", markF));
}
}
#Buddy is on the right rack but it's more than that. All of the if statements with more than one line need to have braces.
Otherwise only the first line is read by the compiler. According to Oracle:
Deciding when to omit the braces is a matter of personal taste. Omitting them can make the code more brittle. If a second statement is later added to the "then" clause, a common mistake would be forgetting to add the newly required braces. The compiler cannot catch this sort of error; you'll just get the wrong results.
eg:
if (letter.equals("A")) {
letterA++;
a+=letterA;
}
if (letter.equals("B")) {
letterB++;
b+=letterB;
}

Bubble Sort with compare method not running

This is a follow-up to my previous question that I asked yesterday. I wrote a Bubble Sort method that analyzes an array of strings and returns the NUMBER of comparisons that the method has made when ordering the array into alphabetical order (the assignment is to write several types of sorting methods and graph the number of comparisons each one makes, to see which is most efficient).
This is my code:
public static void main(String[] args)
{
String[] test_array = {"bill", "phil", "adam"};
/*
System.out.println(compare("orange", "boogie"));
*/
System.out.println(bubbleSort(test_array));
}
public static int compare(String a, String b)
{
int len = Math.min (a.length(),b.length());
// looping through every character. If cha is less than chb, the method returns -1, and so on.
for (int i = 0; i<len; i++) {
char cha = a.charAt(i);
char chb = b.charAt(i);
if (cha < chb) {
return -1;
} else if (cha > chb) {
return 1;
}
}
// Now we account for the length of the word, since it could be the same word.
if (a.length() < b.length())
return -1;
else if (a.length() > b.length())
return 1;
// Seems to be the same String, so return 0.
else
return 0;
}
public static int bubbleSort(String[] test_array) {
boolean swapped = true;
// Variable to track number of comparisons.
int compNumber = 0;
while (swapped == true) {
swapped = false;
for (int i = 1; i < test_array.length; i++) {
// Tracking the number of comparisons
compNumber++;
if (compare(test_array[i-1], test_array[i]) > 0) {
//Switching the variables by use of a temp variable
String temp = test_array[i-1];
test_array[i-1] = test_array[i];
test_array[i] = temp;
swapped = true;
}
else {
swapped = true;
}
}
}
return compNumber;
}
So the compare method compares two strings (given by the array) and determines if they are in alphabetical order (returns -1) or not (returns 1), or is the same word (returns 0). Then, the bubble sort method calls upon the compare method to go through the array, and it then makes the switches, while my compNumber variable counts the number of times the loop (therefore the number of comparisons) runs.
It compiles fine, but it unfortunately doesn't stop running and doesn't return anything. I've waited 5 minutes so I've determined that something is wrong, probably with my loops. I can't seem to find an issue, having manipulated the parameters of the loops several times. Could anyone help me out? Thanks in advance.
"swapped" will always be true, hence the while will never end looping.
I think you meant to put swapped = false in the else statement
you need to set one of these two swapped = false... or else you will never exit the while loop because swapped = true always ... probably changing the second one makes sense !
if (compare(test_array[i-1], test_array[i]) > 0) {
//Switching the variables by use of a temp variable
String temp = test_array[i-1];
test_array[i-1] = test_array[i];
test_array[i] = temp;
swapped = true;
}
else {
swapped = true;
}

Categories

Resources