Simple return statement error - java

I'm trying to make a program that returns a letter grade for whatever number grade you put into it but java keeps telling me I'm missing a return statement. I've tried changing char to void to int but none of those worked. I'm still a newbie so any help would be appreciated.
class Grades
{
public static char getGrade(int x)
{
char A, B, C, D, F;
if((x>=90) && (x<=100))
return 'A';
if((x>=80) && (x<=89))
return 'B';
if((x>=70) && (x<=79))
return 'C';
if((x>=65) && (x<=69))
return 'D';
if(x<65)
return 'F';
}
public static char getGrade(int y, int z)
{
int w = ((y + z)/2);
return getGrade(w);
}
public static void main(String[] args)
{
System.out.println("64 gets the grade " + getGrade(64));
System.out.println("99 gets the grade " + getGrade(99));
System.out.println("73 and 91 gets the grade " + getGrade(73,91));
}
}
Every time I use this code I always receive the error:
Grades.java:17: error: missing return statement
}
Why is this?

You should always have a 100% probability to return something, which was not the case here.
public int returnAnInt(int a){
if (a > 0) return 10;
}
This code wouldn't work because it is not guarenteed that a is always superior to 0. Imagine have -1 as a parameter.. What would it return?
Check the correction :
public int returnAnInt (int a){
if (a > 0) 10;
else return 0;
}
Because you're anticipating all the possibilities, this will compile.
You can set F as the default return value here :
public static char getGrade(int x)
{
if((x>=90) && (x<=100))
return 'A';
if((x>=80) && (x<=89))
return 'B';
if((x>=70) && (x<=79))
return 'C';
if((x>=65) && (x<=69))
return 'D';
else
return 'F';
}
It will work in this condition but is not optimal in most situations. It is up to you to find the best correction possible to your own code.
I gave you the right path here.

You're not guaranteed to return anything from your if statement. You have to add an else or return some default value.
If you want to keep the code the same, then place return 'F'; at the end of the method. No need to check if it is an F; it is by elimination.
For instance, that would mean the code would look as follows.
public static char getGrade(int x) {
if((x>=90) && (x<=100)) {
return 'A';
}
if((x>=80) && (x<=89)) {
return 'B';
}
if((x>=70) && (x<=79)) {
return 'C';
}
if((x>=65) && (x<=69)) {
return 'D';
}
return 'F';
}
As an alternative, consider including else if statements, since that would make this a bit clearer.

The compiler cannot ensure that there is a return. Have a look at the following example:
public boolean mod2(int a){
if(a % 2 == 0)
return true;
if(a % 2 != 0)
return false;
}
This method will return for any given value but the compiler can only check snytax not semantics. And therefore the code is not compilable.
You need something like a default case which will match if none of the above statements will match.
With the code above it will be:
public boolean mod2(int a){
if(a % 2 == 0)
return true;
else
return false;
}

Note that you can avoid repeating the grade boundaries by using TreeMap:
public static char getGrade(int x) {
NavigableMap<Integer, Character> grades = new TreeMap<Integer, Character>();
grades.put(90, 'A');
grades.put(80, 'B');
grades.put(70, 'C');
grades.put(65, 'D');
grades.put(Integer.MIN_VALUE, 'F');
return grades.floorEntry(x).getValue();
}
If you know that the number grades are non-negative, you can replace Integer.MIN_VALUE with 0 for better readability.
If, on the other hand, you want the method to reject number grades higher than 100, you will need to add some validation at the top of the method.
If the grade calculation is performance critical, it is better to initialize the map just once, somewhere outside the getGrade method.

Related

How to use a "Do While" loop to iterate through a list

public static boolean hasGreaterDoWhile(List<Integer> numbers, int number) {
int d = 0;
do {
if (numbers.get(d) > number){
return true;
}
d++;
}
while (d < numbers.size());
return false;
}
(JAVA only)
P.s This is a function i have tried, in order to check the first argument, and if it contains a number that is larger than the second argument, it will then return true, and flase otherwise.
Note that it is using do while loop. I just don't know which part of this code i have done wrong, because the system keeps telling me that "java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0".
Thank u, any hint will be much appriciated.
your list of Integers is empty. you can't access an index of an empty list:
public static boolean hasGreaterDoWhile(List<Integer> numbers, int number) {
int d = 0;
if (numbers.isEmpty()) return false;
do {
if (numbers.get(d) > number){
return true;
}
d++;
}
while (d < numbers.size());
return false;
}
A do-while control block works as follows:
Execute the do block
Check the condition. If it holds, return to (1)
Notice the order of this flow. Unlike a standard while, do-while will always execute one iteration before checking the condition. Therefore, for an empty list you will always try to access the 0-index element of the table, which does not exist, hence the error. You can use a while loop to avoid this:
public static boolean hasGreaterDoWhile(List<Integer> numbers, int number) {
int d = 0;
while (d < numbers.size()) {
if (numbers.get(d) > number){
return true;
}
d++;
}
return false;
}
You should check whether the collection is empty
like this
if(numbers == null || numbers.isEmpty()) {
return false;
}
int d = 0;
do {
if (numbers.get(d) > number){
return true;
}
d++;
}
while (d < numbers.size());
return false;

Recursive implementation of indexOf

I've already read many previous questions here and elsewhere, but I haven't found what I need.
I need to write a recursive implementation of indexOf. The problem is that I can't use any local variables and have to give as input only a string and a char.
The method should return a value between 0 and the length of the string - 1 if the char has been found or -1 if it is not there.
I know the actual 'indexOf' allows you to search for a string too, but this method is simplified.
I tried this but it's quite stupid since I used the real indexOf:
public static int indexOf(String s, char c){
if(s.indexOf(c) < 0){ // I'd like to change this
return -1;
}
if (s.length() == 0) //base case #1
{
return -1;
}
else if (s.charAt(0) == c) //base case #2
{
return 0;
}
else {
return 1 + indexOf(s.substring(1), c);
}
}
I saw this in particular, but is it possibile to write it without variables? Thanks
If you don't want local variables, you need to do the recursion in an internal method.
Advantage is that it's a lot faster, since it doesn't have to create new String objects, and the logic is tail-recursive, if used with a language that optimizes that.
public static int indexOf(String s, char c) {
return indexOf0(s, c, 0);
}
private static int indexOf0(String s, char c, int index) {
if (index == s.length())
return -1;
if (s.charAt(index) == c)
return index;
return indexOf0(s, c, index + 1);
}
The answer that you linked seems to be a good one... I recommend simply replacing the instances of the variable used in it with the method call the variable stores.
Below I simply edit the code:
public static int indexOf(char ch, String str) {
// Returns the index of the of the character ch
if (str == null || str.equals("")) {
// base case: no more string to search; return -1
return -1;
} else if (ch == str.charAt(0)) {
// base case: ch is at the beginning of str; return 0
return 0;
}
return indexOf(ch, str.substring(1)) == -1 ? -1 : 1 + indexOf(ch, str.substring(1));
}

Beautiful Word:Hackerrank

Question
We consider a word,w , to be beautiful if the following two conditions are satisfied:
No two consecutive characters are the same.
No two consecutive characters are in the following vowel set: a, e, i, o, u, y. Note that we consider y to be a vowel in this challenge.
For example:
The string batman is beautiful because it satisfies the given criteria; however, apple has two consecutive occurrences of the same letter (pp) and beauty has three consecutive vowels (eau), so those words are not beautiful.
My problem is when i am giving an input string "yes" it prints Yes but it should print No.
When i debugged the code using Intellij i see that
It is executing the code which is past return statement but the return statement is used to transfer control to the main function.
Solution
public class Coding {
int count = 0;
public static void main(String[] args) {
Coding obj = new Coding();
Scanner in = new Scanner(System.in);
String w = in .next();
boolean b = true;
char[] c = w.toCharArray();
for (int i = 0; i < c.length - 2; i++) {
b = obj.check(i, c); //recursive function
if (c[i] == c[i + 1]) {
b = false;
break;
}
if (!b) {
System.out.println("No");
break;
}
}
if (c[c.length - 2] == c[c.length - 1]) //check.for.the.remaining.chars
System.out.println("No");
else if (b) {
System.out.println("Yes");
}
}
public boolean check(int i, char[] c) {
if (c[i] == 'a' || c[i] == 'e' || c[i] == 'i' || c[i] == 'o' || c[i] == 'u' || c[i] == 'y') {
count++;
if (count == 2) {
return false; // code following this statement are executing
}
check(i + 1, c);
}
count = 0;
return true;
}
}
You are making a recursive call, but you are ignoring the results of that call!
That doesn't make sense. Either that call is valid, then you should return whatever comes back. Or the recursion doesn't "belong" there, then you should rework the complete method!
Beyond that: although recursive solution often look elegant, those contests focus on optimal performance. Meaning: rather use a single loop to iterate that string once.
Hint: The problem appears to be with method count. It always returns true to main method. If any recursive call returns false, is it being propagated back to main method?

Why is the method not acting "properly?"

I get the numbers scanned in correctly, but the methods aren't working right. First one doesn't do anything and the second one goes into an infinite loop.
Method called is not performing correctly. I am not sure what to do.
import java.util.Scanner;
public class testSequence {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter a number: ");
int enterNumber = scan.nextInt();
System.out.println("1 for Iteration, 2 for Recursion: ");
int type = scan.nextInt();
if (type == 1){
computeIteration(enterNumber);
} else if (type == 2){
computeRecursion(enterNumber);
}
}
public static int computeIteration(int enterNumber) {
int answer;
int multiplier = 1;
int count = 0;
int addend = 0;
if (enterNumber == 0) {
count++;
return enterNumber;
} else if (enterNumber == 1) {
count++;
return enterNumber;
} else {
for (int i = 0; i <= enterNumber; i++) {//need to adjust "i" for counter correction
enterNumber = (multiplier * 2) + addend;
addend = multiplier;
multiplier = enterNumber;
count += 1;
}//end for loop
answer = enterNumber;
}//end else
return answer;
}//end computeIteration
public static int computeRecursion(int n) {
int count = 0;
if (n == 0) {
count++;
return 0;
} else if (n == 1) {
count++;
return 1;
} else {
count++;
return computeRecursion(2 * (n - 1)) + computeRecursion(n - 2);
}
}//end computerRecursion()
}//end Sequence()
You're never printing the answer.
if (type == 1){
computeIteration(enterNumber);
} else if (type == 2){
computeRecursion(enterNumber);
}
Note how you're calling the functions, but you never do anything with the result.
You probably meant:
if (type == 1){
System.out.println(computeIteration(enterNumber));
} else if (type == 2){
System.out.println(computeRecursion(enterNumber));
}
Or, if you wanted to get fancy:
UnaryOperator<Integer> f =
type == 1 ?
computeIteration
: computeRecursion;
System.out.println( f.apply(enterNumber) ) ;
Just an addition since you asked. I'm using the ternary operator because I need to choose between 2 things. In a case like this, it's neater than a full if statement.
The UnaryOperator is a functional interface. Basically, using them, you can save a function inside a variable. This is useful where in cases like this, you want to choose between 2 functions whose signatures are the same (both of your functions take an int, and give back an int), and use the result.
I save one of your functions into f, then call it by writing f.apply(9) (apply "applies" the arguments to the function; calling it).
Note you shouldn't use functional interfaces just for kicks, as they can make code less clear. When used properly though, they can make code much simpler; especially when paired with anonymous functions.

Password Validator

I'm currently trying to make a password validator work with boolean method, since the teacher asked us to do so. This is driving me nuts. To be correct, the password need to have one uppercase, one lower case letter, at least 10 characters and one number. I'm aware that right now, my method returns entirely with the value false, but I'm wondering how I can break the code once I have one uppercase, or one lowercase.
Thanks a lot for your help!
public class AtLeast1UppercaseLowercaseNumber {
public static void main(String[] args){
String password = "H";
System.out.println(password);
if(isSecurePassword(password)){
System.out.println("Yay it works");}
else {
System.out.println("you suck");}
}
public static isSecurePassword(String password) {
int uppercase = 0, lowercase = 0, number = 0;
for(int i=0; i<password.length(); i++) {
for(char c ='A'; c <='Z'; c++) {
if(password.charAt(i) == c) {
uppercase++;
if( uppercase >= 1) {
for(char t = 'a'; t <='z'; t++) {
if(password.charAt(i) == t) {
lowercase++;
if(lowercase >= 1) {
}
}
}
for(int j = '0'; j <='9'; j++) {
if(password.charAt(i) == j) {
number++;
if( number >= 1) {
}
}
}
}
return false;
}
}
I suggest you start by creating multiple private and static test methods, and then delegate to them in your public isSecurePassword(String) method. Implement test methods like boolean oneUpper(String), boolean oneLower(String), boolean oneDigit(String) and boolean tenCharacters(String) as an example
private static boolean tenCharacters(String str) {
return str.length() > 9;
}
and a second example
private static boolean oneUpper(String str) {
for (char ch : str.toCharArray()) {
if (Character.isUpperCase(ch)) {
return true;
}
}
return false;
}
Then your isSecurePassword(String) is just
public static boolean isSecurePassword(String str) {
return tenCharacters(str) && oneUpper(str) && oneLower(str)
&& oneDigit(str);
}
Since there is only one return in this method, which explicitly returns false, this method will always return false.
Method 1:
Define a boolean, which will be returned in the last statement of the method. This boolean is true by default and will be set false if one condition is wrong.
Method 2:
The last statement is an implicit return true statement, and whenever a condition is not fullfilled return false. This will prevent the method from executing more tests.
Method 3:
Make the method look like this
if (containsUpperCase(string) && contains...)
return true;
return false;

Categories

Resources