Compiling Error: Missing return statement [duplicate] - java

This question already has answers here:
"Missing return statement" within if / for / while
(7 answers)
Closed 8 years ago.
This program plays craps with 3 different methods. I need help in playing craps but i'm required to have these 3 different methods but for some reason every time I compile I am getting this error:
CrapsAnalysis.java:48: error: missing return statement
}
^
1 error
Process javac exited with code 1
Code:
public class CrapsAnalysis
{
public static int rollDie( int n) {
return (int)(Math.random()*n) + 1 ;
}
public static int rollDice( ) {
return rollDie(6) + rollDie(6) ;
}
public static boolean playOneGame( ) {
int newDice = rollDice();
int roll = rollDice(); //first roll of the dice
int playerPoint = 0; //player point if no win or loss on first roll
if (roll == 7 || roll == 11)
return true;
else if (roll == 2 || roll == 3 || roll == 12)
return false;
else
playerPoint = roll;
do {
if (rollDice() == 7)
return false;
else if (rollDice() == playerPoint)
return true;
else
newDice = rollDice();
} while (rollDice() != playerPoint || rollDice() != 7) ;
}
}

Java must look at all execution paths. What happens if the while loop ends without returning anything? You may be logically preventing that, but the Java compiler won't do that analysis.
Provide a return statement after the end of the while loop, or throw some kind of an Exception (IllegalStateException?) if the code really shouldn't ever make it there.

You can add the last return statement after your code like this:
public static boolean playOneGame() {
int newDice = rollDice();
int roll = rollDice(); // first roll of the dice
int playerPoint = 0; // player point if no win or loss on first roll
if (roll == 7 || roll == 11)
return true;
else if (roll == 2 || roll == 3 || roll == 12)
return false;
else
playerPoint = roll;
do {
if (rollDice() == 7)
return false;
else if (rollDice() == playerPoint)
return true;
else
newDice = rollDice();
} while (rollDice() != playerPoint || rollDice() != 7);
return false;
}
It will make it compile and your code will still work.

you only return statements are inside the body of an if block.
The compiler doesn't know if any of those if blocks will ever be reached, so it's giving you an error.
You might want to have a default return statement at the end
} while (rollDice() != playerPoint || rollDice() != 7) ;
return false;
}
I'm assuming that if that default return statement ever actually gets executed, than it's an error state, and you should react accordingly.

You are missing a return in your while block:
public static boolean playOneGame( ) {
int newDice = rollDice();
int roll = rollDice(); //first roll of the dice
int playerPoint = 0; //player point if no win or loss on first roll
if (roll == 7 || roll == 11)
return true;
else if (roll == 2 || roll == 3 || roll == 12)
return false;
else
playerPoint = roll;
do {
if (rollDice() == 7)
return false;
else if (rollDice() == playerPoint)
return true;
else
newDice = rollDice();
} while (rollDice() != playerPoint || rollDice() != 7)
**// You are missing a return statement here.**;

public static boolean playOneGame( ) {
int newDice = rollDice();
int roll = rollDice(); //first roll of the dice
int playerPoint = 0; //player point if no win or loss on first roll
if (roll == 7 || roll == 11)
return true;
else if (roll == 2 || roll == 3 || roll == 12)
return false;
else
playerPoint = roll;
do {
if (rollDice() == 7)
return false;
else if (rollDice() == playerPoint)
return true;
else
newDice = rollDice();
} while (rollDice() != playerPoint || rollDice() != 7) ;
return SOMETHING HERE;
}
You should look into consistent code formatting. Not only for us, but for yourself as well so when you look at this code after a few weeks you can still read it.

When you have to add return make sure you add return for every possible execution path of add a default return statement. You program is missing both of them
public class CrapsAnalysis
{
public static int rollDie( int n) {
return (int)(Math.random()*n) + 1 ;
}
public static int rollDice( ) {
return rollDie(6) + rollDie(6) ;
}
public static boolean playOneGame( ) {
int newDice = rollDice();
int roll = rollDice(); //first roll of the dice
int playerPoint = 0; //player point if no win or loss on first roll
if (roll == 7 || roll == 11)
return true;<--- Works
else if (roll == 2 || roll == 3 || roll == 12)
return false;<--- Works
else
playerPoint = roll;
do {
if (rollDice() == 7)
return false;<--- Works
else if (rollDice() == playerPoint)
return true;<--- Works
else
newDice = rollDice();
} while (rollDice() != playerPoint || rollDice() != 7) ;
//No return here. You need to add a default return if none of the conditions above satisfies
}
}

Here is a very stripped down version of your code:
public static boolean playOneGame()
{
if(condition1 == true)
{
//code1
return true;
}
else if(condition2 == true)
{
//code2
return false;
}
else
{
//code3
}
//code4
}
If condition1 or condition2 is true, playOneGame() will return either true of false. However, if condition1 and condition2, are both false, the only code that will run is code3. code3 does not contain a return statement, so it is theoretically possible that playOneGame() will not return anything. You know that condition1 and condition2 will never both be false, but the java compiler does not, so it throws a compiler error. If it did not throw a compiler error and condition1 and condition2 somehow both became false, it would throw a runtime error. Runtime errors are a lot harder to debug than compiler errors, so the compiler is doing you a favor by throwing an easy-to-fix error.
To fix the missing return statement, add a return statement to code3 or code4.

After your while loop you need a return statement, because the if/else statements may or may not be executed. If none of them execute, you have no return. Therefore, you need to ensure that there will be at least one return statement that can always be executed.
public static boolean playOneGame( ) {
int newDice = rollDice();
int roll = rollDice(); //first roll of the dice
int playerPoint = 0; //player point if no win or loss on first roll
if (roll == 7 || roll == 11)
return true;
else if (roll == 2 || roll == 3 || roll == 12)
return false;
else
playerPoint = roll;
do {
if (rollDice() == 7)
return false;
else if (rollDice() == playerPoint)
return true;
else
newDice = rollDice();
} while (rollDice() != playerPoint || rollDice() != 7) ;
return false;
}
Also, for clarity, I rearranged your if/else statements so it is easier to read. You might want to get into the habit of doing this as well so that others can have an easier time understanding your code.

Related

Are there any efficient micro-optimizations to find the number of unique grid paths?

I am trying to solve this CSES problem: Grid Paths. You are given a string of length 48, and you have to find the amount of paths such that you traverse all of the grid and end up at the lower left corner.
I believe I have pruned the search to the best of my ability, as according to this book: CP Handbook (Look in the pruning the search category), the best optimization for this type of problem is to prevent your path from closing yourself off, and I have already implemented this. The time limits for this specific problem are tight, and although I have basically solved this problem, I am still failing 1-2 test cases because my solution takes around 1.01 seconds instead of being below the 1 second time limit.
Finally, I just wanted to know if there were any cool micro-optimizations I could use to marginally enhance the speed of my java code, so I could actually pass all of the test cases for this problem.
import java.io.*;
public class GridPaths {
public static class FastIO {
InputStream dis;
byte[] buffer = new byte[1 << 17];
int pointer = 0;
public FastIO(String fileName) throws Exception {
dis = new FileInputStream(fileName);
}
public FastIO(InputStream is) {
dis = is;
}
int nextInt() throws Exception {
int ret = 0;
byte b;
do {
b = nextByte();
} while (b <= ' ');
boolean negative = false;
if (b == '-') {
negative = true;
b = nextByte();
}
while (b >= '0' && b <= '9') {
ret = 10 * ret + b - '0';
b = nextByte();
}
return (negative) ? -ret : ret;
}
long nextLong() throws Exception {
long ret = 0;
byte b;
do {
b = nextByte();
} while (b <= ' ');
boolean negative = false;
if (b == '-') {
negative = true;
b = nextByte();
}
while (b >= '0' && b <= '9') {
ret = 10 * ret + b - '0';
b = nextByte();
}
return (negative) ? -ret : ret;
}
Integer[] readArray(int n) throws Exception {
Integer[] a = new Integer[n];
for (int i = 0; i < n; i++) a[i] = nextInt();
return a;
}
byte nextByte() throws Exception {
if (pointer == buffer.length) {
dis.read(buffer, 0, buffer.length);
pointer = 0;
}
return buffer[pointer++];
}
String next() throws Exception {
StringBuilder ret = new StringBuilder();
byte b;
do {
b = nextByte();
} while (b <= ' ');
while (b > ' ') {
ret.appendCodePoint(b);
b = nextByte();
}
return ret.toString();
}
}
static char[] board;
static boolean[][] visited = new boolean[7][7];
static int ans = 0;
public static boolean works(int i, int j) {
//makes sure that current spot is on the 7x7 grid and is not visited
return (i >= 0 && i<=6 && j>=0 && j<=6 && !visited[i][j]);
}
public static void solve(int i, int j, int steps) {
if (i == 6 && j == 0) {
if (steps == 48) ans++; //all spots of the grid have to be visited in order to be counted as part of the answer
return;
}
visited[i][j] = true;
//you are given ? characters in the input string, and those mean that you have to try out all 4 combinations (U,D,L,R)
if (board[steps] == '?' || board[steps] == 'L') {
//second condition of the second if statement checks if the spot directly ahead of the current spot is blocked, and if it is, the left and right spots cannot both be unvisited or else you will not continue searching
if (works(i,j-1) && !(!works(i,j-2) && works(i+1,j-1) && works(i-1,j-1))) {
solve(i, j - 1, steps + 1);
}
}
if (board[steps] == '?' || board[steps] == 'R') {
if (works(i,j+1) && !(!works(i,j+2) && works(i+1,j+1) && works(i-1,j+1))) {
solve(i, j + 1, steps + 1);
}
}
if (board[steps] == '?' || board[steps] == 'U') {
if (works(i-1,j) && !(!works(i-2,j) && works(i-1,j+1) && works(i-1,j-1))) {
solve(i - 1, j, steps + 1);
}
}
if (board[steps] == '?' || board[steps] == 'D') {
if (works(i+1,j) && !(!works(i+2,j) && works(i+1,j+1) && works(i+1,j-1))) {
solve(i + 1, j, steps + 1);
}
}
visited[i][j] = false;
}
public static void main(String[] args) throws Exception {
FastIO in = new FastIO(System.in);
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
board = in.next().toCharArray();
solve(0,0,0);
out.println(ans);
out.close();
}
}
Note: I am already using one of the fastest, if not the fastest, ways to receive input in Java, so I do not believe I can actually improve upon that.
I've been playing around with this. In addition to using a standard mechanism for reading the input file (which I suggested in a comment), you can gain a little time in the search alg itself by doing two things:
Break the case board[steps] == '?' off from the other cases. So check for board[steps] == '?' first, and just try all four directions in that case. Otherwise (the else case for if (board[steps] == '?'), just check for U/D/L/R. Since for most steps, the character will be '?', you save having to make the U/D/L/R tests most of the time.
Look up the character to be tested once, with c = board[steps],and then use c in each test instead of board[steps].
Doing these two things saved about 5% it seems. I was doing 100 reps of the solve and timing with System.currentTimeMillis(). I know there are more accurate ways of timing, but this was good enough to see a definite improvement even though the times jumped around quite a bit trial to trial. The best I ever saw in each case was 3600 millis for 100 iterations as originally written vs 3400 millis with the improvements.
My guess is that it's mostly the first change that matters. I'd expect the compiler to be doing the second already, but I didn't try the two optimizations independently.
I also solved this problem in java (AC), and here is how I did it
public static char[] defaultPath;
public static boolean[][] isUsed;
public static int counter = 0;
public static void solve(int indexChar, int indexRow, int indexColumn) {
if (indexRow == 8 && indexColumn == 2) {
if (indexChar == 48) {
counter++;
}
}else {
// Find correct way: 'D', 'U', 'L', 'R'
char correctWay = '?';
// (1) (1)
// 0 1 or 1 0
// 1 1
if ((isUsed[indexRow+1][indexColumn+1] || isUsed[indexRow+1][indexColumn-1])
&& isUsed[indexRow+2][indexColumn] && !isUsed[indexRow+1][indexColumn]) {
correctWay = 'D';
}
// 1 1
// 0 1 or 1 0
// (1) (1)
else if ((isUsed[indexRow-1][indexColumn+1] || isUsed[indexRow-1][indexColumn-1])
&& !isUsed[indexRow-1][indexColumn] && isUsed[indexRow-2][indexColumn]) {
correctWay = 'U';
}
// 1 0 (1) or 1
// 1 1 0 (1)
else if ((isUsed[indexRow+1][indexColumn-1] || isUsed[indexRow-1][indexColumn-1])
&& !isUsed[indexRow][indexColumn-1] && isUsed[indexRow][indexColumn-2]) {
correctWay = 'L';
}
//(1) 0 1 or 1
// 1 (1) 0 1
else if ((isUsed[indexRow+1][indexColumn+1] || isUsed[indexRow-1][indexColumn+1])
&& !isUsed[indexRow][indexColumn+1] && isUsed[indexRow][indexColumn+2]) {
correctWay = 'R';
}
// Check input path (default path)
char c = defaultPath[indexChar];
if (c == '?') {
if (correctWay == '?') {
// 'D'
if (!isUsed[indexRow+1][indexColumn]) {
isUsed[indexRow+1][indexColumn] = true;
solve(indexChar+1, indexRow+1, indexColumn);
isUsed[indexRow+1][indexColumn] = false;
}
// 'U'
if (!isUsed[indexRow-1][indexColumn]) {
isUsed[indexRow-1][indexColumn] = true;
solve(indexChar+1, indexRow-1, indexColumn);
isUsed[indexRow-1][indexColumn] = false;
}
// 'L'
if (!isUsed[indexRow][indexColumn-1]) {
isUsed[indexRow][indexColumn-1] = true;
solve(indexChar+1, indexRow, indexColumn-1);
isUsed[indexRow][indexColumn-1] = false;
}
// 'R'
if (!isUsed[indexRow][indexColumn+1]) {
isUsed[indexRow][indexColumn+1] = true;
solve(indexChar+1, indexRow, indexColumn+1);
isUsed[indexRow][indexColumn+1] = false;
}
}else {
if (correctWay == 'D') {
isUsed[indexRow+1][indexColumn] = true;
solve(indexChar+1, indexRow+1, indexColumn);
isUsed[indexRow+1][indexColumn] = false;
}else if (correctWay == 'U') {
isUsed[indexRow-1][indexColumn] = true;
solve(indexChar+1, indexRow-1, indexColumn);
isUsed[indexRow-1][indexColumn] = false;
}else if (correctWay == 'L') {
isUsed[indexRow][indexColumn-1] = true;
solve(indexChar+1, indexRow, indexColumn-1);
isUsed[indexRow][indexColumn-1] = false;
}else if (correctWay == 'R') {
isUsed[indexRow][indexColumn+1] = true;
solve(indexChar+1, indexRow, indexColumn+1);
isUsed[indexRow][indexColumn+1] = false;
}
}
}else {
if (c == correctWay || correctWay == '?') {
if (c == 'D' && !isUsed[indexRow+1][indexColumn]) {
isUsed[indexRow+1][indexColumn] = true;
solve(indexChar+1, indexRow+1, indexColumn);
isUsed[indexRow+1][indexColumn] = false;
}else if (c == 'U' && !isUsed[indexRow-1][indexColumn]) {
isUsed[indexRow-1][indexColumn] = true;
solve(indexChar+1, indexRow-1, indexColumn);
isUsed[indexRow-1][indexColumn] = false;
}else if (c == 'L' && !isUsed[indexRow][indexColumn-1]) {
isUsed[indexRow][indexColumn-1] = true;
solve(indexChar+1, indexRow, indexColumn-1);
isUsed[indexRow][indexColumn-1] = false;
}else if (c == 'R' && !isUsed[indexRow][indexColumn+1]) {
isUsed[indexRow][indexColumn+1] = true;
solve(indexChar+1, indexRow, indexColumn+1);
isUsed[indexRow][indexColumn+1] = false;
}
}
}
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
defaultPath = scanner.next().toCharArray();
isUsed = new boolean[11][11];
for (int i = 0; i < 11; i++) {
isUsed[0][i] = true;
isUsed[1][i] = true;
isUsed[9][i] = true;
isUsed[10][i] = true;
isUsed[i][0] = true;
isUsed[i][1] = true;
isUsed[i][9] = true;
isUsed[i][10] = true;
}
isUsed[2][2] = true;
isUsed[8][1] = false;
isUsed[9][2] = false;
solve(0, 2, 2);
System.out.println(counter);
scanner.close();
}

My code in adding condition of range 1 - 9999 is not working using switch statement

So I created LeapYearCal this on If else statement I learn switch statement I want to recreate it using switch.
Somehow my condition for leap is working, but I want to add condition like value must be in 1- 9999 only else it'll returned false. but when my code is incorrect How do I solve the problem?
public static boolean isLeapYear(int year)
{
switch ( year % 4)
{
case 0:
if (year % 100 == 0)
{
if ( (year % 400 == 0) )
{
if (year > 0)
{
if (year <= 9999)
{
return true;
}
else
return false;
}
else
return false;
}
else
return false;
}
else
return true;
default:
break;
}
return false;
I want to the output "True" if the year is Leap year and it's range 1-9999 else "False" if it is not in range regardless if its leap year
Using switch-case statement in this use-case is inappropriate. This solution is based on this code :
public static boolean isLeapYear(int year){
boolean flag = false;
if (year > 0 && year < 10000)
{
flag = false;
}
else if(year % 400 == 0)
{
flag = true;
}
else if (year % 100 == 0)
{
flag = false;
}
else if(year % 4 == 0)
{
flag = true;
}
else
{
flag = false;
}
return flag;
}

Getting a return line error for my method?

public static boolean isValidDate(int month, int day) {
if (month >= 3 && month <= 5) {
if (month == 3) {
if (day >= 1 && day <= 31) {
return true;
} else {
return false;
}
} else if (month == 4) {
if (day >= 1 && day <= 30) {
return true;
} else {
return false;
}
} else if (month == 5) {
if (day >= 1 && day <= 15) {
return true;
} else {
return false;
}
}
} else {
return false;
}
}
Get these errors:not sure how to fix them im returning everything.
BoxOffice.java:81: error: missing return statement
}
BoxOffice.java:85: error: missing return statement
}
The compiler isn't smart enough to deduce that the inner if covers every scenario in the range of the outer if. Just change
else if(month == 5) {
to
else { // month must be 5 here
shmosel's answer describes the problem and the least disruptive fix.
Personally, I'd write this as a switch, and avoid writing the long if/else statements to check the day:
switch (month) {
case 3:
return (day >= 1 && day <= 31);
case 4:
return (day >= 1 && day <= 30);
case 5:
return (day >= 1 && day <= 15);
default:
return false;
}
you need to transforme the else if (month == 5) to else ....
public static boolean isValidDate(int month, int day)
{
if (month >= 3 && month <= 5)
{
if (month == 3)
{
if (day >= 1 && day <= 31)
{
return true;
}
else
{
return false;
}
}
else if (month == 4)
{
if (day >= 1 && day <= 30)
{
return true;
}
else
{
return false;
}
}
else
{
if (day >= 1 && day <= 15)
{
return true;
}
else
{
return false;
}
}
}
else
{
return false;
}
}
Try making a boolean, and instead of returning in the if statement, change the boolean and return at the end of the method. Here is an example with your code.
public static boolean isValidDate (int month, int day) {
boolean result = true; //This must be set to a value to avoid compiler errors
if(month >= 3 && month <= 5) {
if(month == 3) {
if(day >= 1 && day <= 31) {
result = true;
}
else {
result = false;
}
}
else if(month == 4) {
if(day >= 1 && day <= 30) {
result = true;
}
else {
result = false;
}
}
else if(month == 5) {
if(day >= 1 && day <= 15) {
result = true;
}
else {
result = false;
}
}
}
else {
result = false;
}
return result;
}
Hope that helps!

Unreachable Statement in my Public Boolean Method

So I'm trying to create an isValid method that verifies if a certain date is real or not (i.e. 3/31/2016 is valid, 2/29/2001 is valid since it's a leap year, 2/30/2016 is not valid)
Here is my method public boolean isValid()
`
{
//January
if (month == 1 && day <= 31) {
return true;
}
else {
return false;
}
//February
if (month == 2 && day <= 28) {
return true;
}
else {
if ((((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0)) {
if (day == 29) {
return true;
}
else {
return false;
}
}
else {
return false;
}
}
//March
if (month == 3 && day <= 31) {
return true;
}
else {
return false;
}
//April
if (month == 4 && day <= 30) {
return true;
}
else {
return false;
}
//May
if (month == 5 && day <= 31) {
return true;
}
else {
return false;
}
//June
if (month == 6 && day <= 30) {
return true;
}
else {
return false;
}
//July
if (month == 7 && day <= 31) {
return true;
}
else {
return false;
}
//August
if (month == 8 && day <= 31) {
return true;
}
else {
return false;
}
//September
if (month == 9 && day <= 30) {
return true;
}
else {
return false;
}
//October
if (month == 10 && day <= 31) {
return true;
}
else {
return false;
}
//November
if (month == 11 && day <= 30) {
return true;
}
else {
return false;
}
//December
if (month == 12 && day <= 31) {
return true;
}
else {
return false;
}
}
`
Now, when I compile, it says there are unreachable statements essentially wherever it says "if". Could somebody please help? I've already tried the 'if (true) {return}' method and I can't find anything else helpful.
In your first if statement, it returns regardless of outcome, meaning all the following if statements will never be reached as if your first condition is not met it will return, and if it is, it also returns.
A fix for this is to remove all your else return false paths and string all if statements in an else if chain and then return false at the end of that.
e.g.
if(){
...
}else if(){
...
}
return false;
Your code should if elseif elseif elseif... else...
when you say if and else.. your code will end either in if or else.. henceforth other if statements are unreachable...
that is the error you are getting...change other conditions to elseif
Your code will never go to the second if statement as the else part of first(January's) will terminate your program
Your code has to be like:
if(month == 1)
{
if(day <= 31)
return true;
else
return false;
}
if(month==2)
{
----
----
}
return **statement should be last statement of any method**
else you can use variable instead of direct return statement like
public boolean isValid()
{
boolean status=false;
if(condition)
{
status=true;
}
return status;
}

Why doesn't this array check work?

I am trying to check an array for a 1 or a 3, if either is found, print false, else print true. I ahve this:
if(array[i] == 1){
bool = false;
}
else if(array[i] == 3){
bool = false;
}
else{
bool = true;
}
However it does not work in all cases.
If the input is 0 2 4 it prints true as it should.
but if the input is 4 2 7 1 8 it should be false as there is a 1, but it prints true.
What am i doing wrong?
EDIT: Added a break to the if and changed the if statement. Works now.
if(array[i] == 1 || array[i] == 3){
bool = false;
break;
}
else{
bool = true;
}
A better approach is
boolean flag = true;
for(int i=0; i<myArray.length; i++)
{
if(myArray[i]==1 || myArray[i]==3){
flag = false;
break;
}
}
return flag;
this code
if(array[i] == 1 || array[i] == 3){
bool = false;
break;
}
else{
bool = true;
}
equal
if(array[i] == 1){
bool = false;
}else{
bool = true;
}
if(array[i] == 3){
bool = false;
}
else{
bool = true;
}

Categories

Resources