Questions on if and else statements - java

This is the question I saw on CodingBat:
Given 2 positive int values, return the larger value that is in the range 10..20 inclusive, or return 0 if neither is in that range.
And this is the code I have written:
public int max1020(int a, int b) {
if ( a>=10 && a<=20 && b>=10 && b<=20 && a>b)
return a;
if (a>=10 && a<=20 && b>=10 && b<=20 && b>a)
return b;
if (a>=10 && a<=20 && b<=10 || b>=20)
return a;
if (a<=10 || a>=20 && b>=10 && b<=20)
return b;
else return 0;
}
I am fairly confident that it is correct but still then I click run, the websites says that: max1020(9, 21) → 0 BUT my code returns 9. Can someone help me to check through my codes what is wrong with it? :)

public int max1020(int a, int b) {
if ( a>=10 && a<=20 && b>=10 && b<=20 && a>b)
return a;
if (a>=10 && a<=20 && b>=10 && b<=20 && b>a)
return b;
if ((a>=10 && a<=20) && (b<=10 || b>=20))
return a;
if ((a<=10 || a>=20) && (b>=10 && b<=20))
return b;
else return 0;
}
Adding brackets in 3rd and 4th line will fix the problem.
I suggest you change the if statements and use else if. It is just good coding practice to use else if statements instead of several if when possible.

Your code is breaking in the third if condition, where you have || b>=20. 3rd and 4th conditions should be more specific like below:
if (a>=10 && a<=20 && (b<=10 || b>=20))
return a;
if ((a<=10 || a>=20) && b>=10 && b<=20)
return b;
Adding these parentheses will do the trick.

i would prefer to assign the checks to a variable to have a more "readable" code. but this depends on personal preferences.
public int max1020(int a, int b) {
final boolean aInRange = a>=10 && a<=20;
final boolean bInRange = b>=10 && b<=20;
if (aInRange && bInRange) {
if (a > b) {
return a;
} else if (a < b) {
return b;
} else {
return 0;
}
} else if (aInRange) {
return a;
} else if (bInRange) {
return b;
} else {
return 0;
}
}

Of course Varun's answer is correct. Additionally, I'd like to elaborate on some comments, and show an alternative approach to the problem that's much simpler and less likely to contain mistakes.
While reading the problem statement, you may notice that the method is to return a value if some conditions are met, or return 0 otherwise. So you could initialize a result with the default value of 0, change the result if the conditions are met, then return the result. That would reduce the code to:
public int max1020(int a, int b) {
int result = 0;
if (a >= 10 && a <= 20) result = a;
if (b >= 10 && b <= 20 && b > result) result = b;
return result;
}
Can't make it much simpler, I'd think. (But if you can, please comment, I love KISS! :) )
This solution produces a slightly different result, if both a and b are in range and a=b, it will return a. The problem statement is not really clear if this should happen, as also shown by the comments to Varun's answer. Coincidentally (or not) Codingbat doesn't check that condition. The proposed solution on the site also returns a in this case.
If you think it should return 0 when a=b, it's quite easy to adjust,
public int max1020(int a, int b) {
int result = 0;
if (a != b) {
if (a >= 10 && a <= 20) result = a;
if (b >= 10 && b <= 20 && b > result) result = b;
}
return result;
}
Still pretty simple :)
To explain TJCrowder's comment about indentation: If you put the body of the if statement on the next line, you should use curly braces and indent the line. Otherwise, it's far too easy to misread it, or make a mistake when you change the code.
// this can be error prone and harder to read,
// especially if you have multiple if statements,
// or add a statement to the body of the if statement in the future
// (shouldn't do this)
if (condition)
statement;
// Personally I think this is totally fine for a simple statement.
// But I know not everybody will agree
if (condition) statement;
// Usually, you'll see this formatting.
// Even without reading anything, the formatting makes it instantly clear
// which statements belong to the body of the if
if (condition) {
statement;
}
Side note: the else statement in your code belongs only to the last if. Your formatting could make that clear by not putting an empty line between those, e.g.
if (condition) statement;
else statement;
if (condition) {
statement;
} else {
statement;
}
In your code the else statement is actually obsolete, you could simply return 0; on the last line.
Varun's suggestion that you could use else ifs is correct. Theoretically, if the condition of the first if statement is true, using else if would make the code skip the tests for the other ifs and be a little more efficient. Additionally, it'd show that subsequent if statements are only reached if the previous if statements were false.
Practically however, in your code it doesn't really matter, because the method will finish and return a value if the condition is true, and subsequent if statements will never be reached anyway.

Related

compareTo() method throwing "This method must return int" error despite returning int in method

I'm working on an assignment for my computer science course requiring me to implement a Comparable interface.
We haven't discussed the interface at any sort of length except just being told it compares two objects and returns less than, greater than and equal to, but literally that's about it, which is frustrating.
I intend to do more research on it, but for now I am finding I'm confused as to why my implementation of the compareTo() method isn't working.
Eclipse is giving me an error that compareTo() must return an int, but if you notice, I am returning an integer value. So what might be the issue?
public int compareTo(Task taskToCompare) {
if(this.complete && taskToCompare.isComplete()) {
if(this.priority == taskToCompare.getPriority()) {
return 0;
}
else if(this.priority < taskToCompare.getPriority()){
return -1;
}
else if(this.priority > taskToCompare.getPriority()) {
return 1;
}
} else if(this.complete == true && taskToCompare.isComplete() == false) {
return -1;
} else if(this.complete == false && taskToCompare.isComplete() == true) {
return 1;
}
}
If the return type is int, you will have to return an int or throw an exception. Just exiting the method without a return will lead to a compiler error.
If you have a if-else-if condition, there may be a case where none of the blocks is called. You therefore should create an else statement with a return.
Also, the result of isComplete() and taskToCompare.getPriority() may change if you call the method multiple times. The compiler doesn't know if your logic prevents that.
For example, this is the case if complete is false and isComplete() also returns false. As before, the compiler doesn't know if your logic prevents that.
I think you want something like:
public int compareTo(Task taskToCompare) {
if(this.complete && taskToCompare.isComplete()) {
if(this.priority == taskToCompare.getPriority()) {
return 0;
}
else if(this.priority < taskToCompare.getPriority()){
return -1;
}
else{
return 1;
}
} else if(this.complete == true && taskToCompare.isComplete() == false) {
return -1;
} else if(this.complete == false && taskToCompare.isComplete() == true) {
return 1;
}else{
return 0;
}
}
What if this.complete == false and taskToCompare.isComplete() == false?
The compiler is complaining because you haven't covered every case.
more compact version:
public int compareTo(Task taskToCompare) {
int completeCompare = (this.complete == taskToCompare.complete) ? 0 : (this.complete ? 1 : -1);
if(completeCompare==0) {
return this.priority-taskToCompare.getPriority();
}
return completeCompare;
}

How can I tell my code that it has a "Flush"?

I'm suppose to create a code that recognizes if my hand has the same card faces
public static boolean sameFace(String hand) {
hand = "s9s7s2sQsK";
char f = hand.charAt(0);
if( hand.charAt(0)==hand.charAt(2) && hand.charAt(0)==hand.charAt(4)
&& hand.charAt(0)==hand.charAt(6) && hand.charAt(0)==hand.charAt(8));
return (hand.charAt(0) == hand.charAt(2) && hand.charAt(0) == hand.charAt(4)
&& hand.charAt(0) == hand.charAt(6) && hand.charAt(0) == hand.charAt(8));
sameface = hand;
if (hand==true;)
return (hand==true;) ;
}
As can be seen above, if all positions are the same characters, it comes true(False, if even one isn't the same.) How can I then use the result of that "return" to let my program recognize it has the same faces or not? If that is even possible.
From what i know, based on my code, it's saying "Yes, positions x=y=z are the same" how can I then tell it "Since they are the same, they have the same card faces."
I tried to put this at the end
sameface = hand;
if (hand==true;)
return (hand==true;) ;
Basically I'm trying to say that when the "hand" return statement is true, then samefaces is true. Meaning that the faces are the same. And if it's false it'll return false.
Basically I'm trying to say that when the "hand" return statement is true, then samefaces is true. Meaning that the faces are the same. And if it's false it'll return false.
You do that simply by returning the result of the expression:
public static boolean sameFace(String hand) {
char f = hand.charAt(0);
return f == hand.charAt(2) &&
f == hand.charAt(4) &&
f == hand.charAt(6) &&
f == hand.charAt(8);
}
Or if you want to be friendly to a different number of cards, use a loop:
public static boolean sameFace(String hand) {
char f = hand.charAt(0);
for (int i = 2, len = hand.length(); i < len; i += 2) {
if (f != hand.charAt(i)) {
// Not a match
return false;
}
}
// All matched
return true;
}

How to compare three boolean values

Compare three boolean values and display the first one that is true.
Hey guys, I am trying to write a program that compares three boolean values and displays the first true one. I am comparing three words for their length, and it will display the longest. The error that I am getting is that my else tags aren't working. Take a look at the code.
//Check which word is bigger
if (len1 > len2)
word1bt2 = true;
if (len2 > len3)
word2bt3 = true;
if (len1 > len3)
word1bt3 = true;
//Check which word is the longest
if (word1bt2 == true && word1bt3 == true);
System.out.println(wor1);
else if (word2bt3 == true);
System.out.println(wor2);
else System.out.println(wor3);
I have set boolean values for word1bt2, word2bt3 and word1bt3. In eclipse, I am getting a syntax error under the elses in my code above. Any help would be great!
if (word1bt2 == true && word1bt3 == true);
Is wrong, you need to remove the semicolon:
if (word1bt2 == true && word1bt3 == true)
Same for the elses
else (word2bt3 == true);
Is wrong too, it should be
else if (word2bt3 == true)
Side note: boolean values can be used as condition, so your if statements should be
if (word1bt2 && word1bt3) // The same as if (word1bt2 == true && word1bt3 == true)
How to compare three boolean values?
Dont!
If you find yourself needing to compare three variable you may as well cater for any number of variables immediately - there's no point hanging around - do it properly straight away.
public String longest(Iterator<String> i) {
// Walk the iterator.
String longest = i.hasNext() ? i.next() : null;
while (i.hasNext()) {
String next = i.next();
if (next.length() > longest.length()) {
longest = next;
}
}
return longest;
}
public String longest(Iterable<String> i) {
// Walk the iterator.
return longest(i.iterator());
}
public String longest(String... ss) {
// An array is iterable.
return longest(ss);
}
Remove the ; and change it with brackets {}.
if (word1bt2 && word1bt3) {
System.out.println(wor1);
} else if (word2bt3) {
System.out.println(wor2);
} else {
System.out.println(wor3);
}
Issue with the else blocks: use {} insteaad of () to enclose instructions...
Remove the ; at the first if!!!!! - Quite common mistake, with very puzzling results!
//Check which word is the longest
if (word1bt2 == true && word1bt3 == true) { //leave ; and always add bracket!
System.out.println(wor1);
}
else if(word2bt3 == true)
{
System.out.println(wor2);
}
else {
System.out.println(wor3);
}
if you need a condition in an else branch, you have to use if again - plain else won't have such a feature...
ALWAYS use brackets for bodies of if statements, loops, etc!!!
Be extremely careful NOT to use ; in the lines that don't behave well with it:
if statements
for loops
while() {...} loops' while statement
try this, if lenght are equal then s1 is considered as Bigger. Also i have not added null check
public class Test {
public static void main(String[] args) {
String word1 = "hi";
String word2 = "Hello";
String word3 = "Hell";
String Bigger = null;
if(word1.length() >= word2.length() && word1.length() >= word3.length() ){
Bigger = word1;
}else if(word2.length() >= word1.length() && word2.length() >= word3.length()){
Bigger = word2;
}else if(word3.length() >= word2.length() && word3.length() >= word1.length()){
Bigger = word3;
}
System.out.println(Bigger);
}
}

java - recursive program for judging the validity of expression syntax (beginner)

I'm just learning java, and I have an assignment where I have to write a program that checks the validity of expressions about sets. Valid expressions are capital letters, an expression with a tilde in front, and can be combined using + and x as well as with parentheses. I've written a program that almost works, but I can't figure out how to get the binary operators to work with the parentheses.
It may also be that I have approached the problem in the wrong way (trying to validate from left to right, ignoring everything to the left once it's been validated). I can use any help I can get about writing recursive programs for this sort of problem; that is, if you have any pointers for a better way of approaching the problem, that would be incredibly helpful.
For reference, here is the code that I have:
public static boolean check(String expr) {
char spot;
int close=0;
expr = expr.trim();
//base case
if (expr.length() == 1 && expr.charAt(0)>= 'A' && expr.charAt(0) <= 'Z')
return true;
if (expr.charAt(0) == '~') {
if (expr.charAt(1) == 'x' || expr.charAt(1) == '+' || expr.charAt(1) == ')')
return false;
return check(expr.substring(1));
}
if (expr.indexOf('x') > 0 && expr.indexOf('x') > expr.indexOf(')')) {
int x = expr.indexOf('x');
if (check(expr.substring(0, x)) && check(expr.substring(x)))
return true;
}
if (expr.indexOf('+') > 0 && expr.indexOf('+') > expr.indexOf(')')) {
int plus = expr.indexOf('+');
if (check(expr.substring(0, plus)) && check(expr.substring(plus+1)))
return true;
}
if (expr.charAt(0) == '(') {
close = findEnd(expr.substring(1));
if (close < 0)
return false;
if (check(expr.substring(1,close)) && check(expr.substring(close+1)))
return true;
}
return false;
}
I'm not sure why your code is that complex. Recursion for this is pretty simple overall; here's what I'd do:
public static boolean check(String str) {
if(str.equals("")) return true;
if(str.charAt(0).isAlphaNumeric() || str.charAt(0) == '(' || str.charAt(0) == ')') return check(str.substring(1));
return false;
}
Your edge cases are if the string is empty; if this is the case, then the string is valid. If the character doesn't match what you're looking for, return false. Otherwise, check the next character.

incomparable type in java

I have got this code, and I get an error incomparable types: java.lang.String and int, for this line of code
if ((this.name.String.compareTo(obj.name == 0)) && (this.age = obj.age))
The method is this:
public int compareTo(Object o)
{
int result;
AnyClass obj = (AnyClass)o;
if ((this.name.String.compareTo(obj.name == 0)) && (this.age = obj.age))
{
result = 0;
}
else if (this.name.compareTo(obj.name) > 0)
{
result = 1;
}
else
{
result = -1;
}
return result;
}
I think that position of your bracket isn't correct,
this.name.String.compareTo(obj.name == 0))
obj.name == 0 is the place where you probably compare String (name) to int (0). I guess you wanted to use compareTo on obj.name and then check if it's equal to zero.
I also think that in the second part
(this.age = obj.age)
You wanted to use == instead of =, so I think that the code you wanted to use is:
((this.name.compareTo(obj.name)==0) && (this.age == obj.age))
You can't compare a string to an integer :)
You can convert the string "001" into the integer "1"; or the integer "1" into the string "1".
See Integer.parseInt() or Integer.toString().
compareTo takes in Objec reference(a string in your case) as argument. But your code compareTo(obj.name == 0) passes in boolean which is not appropriate.
I think the code
if ((this.name.String.compareTo(obj.name == 0)) && (this.age = obj.age))
is actually supposed to read like this
if ((this.name.compareTo(obj.name) == 0) && (this.age == obj.age))
Changing where the == 0 is (and changing the second = to an ==) makes this code make sense.
There are a lot of problems with this implementation. It looks like this is an implementation of Comparable for class AnyClass which means the signature is wrong.
AnyClass should implement Comparable<AnyClass>, and the code should look like this:
#Override
public int compareTo(AnyClass other)
{
int ret = name.compareTo(other.name);
return ret != 0 ? ret : Integer.compare(age, other.age);
}
If you use Guava:
#Override
public int compareTo(AnyClass other)
{
return ComparisonChain.start().compare(name, other.name)
.compare(age, other.age).result();
}
((this.name.String.compareTo(obj.name == 0)) && (this.age = obj.age))
obj.name is a String, and 0 is an int. That's where you're getting the error
obj.name is String and you are comparing it with 0.
It is easier if you explain your intention with the code. The first error seems to be the comparison in compareTo obj.name == 0.
Try
if ((this.name.String.compareTo(obj.name) == 0) && (this.age == obj.age))
Which is what I guess you want to achieve.

Categories