How can I do something like:
int a=5;
if(4<=a<=6){
}
in Java?
Make it two conditions:
int a=5;
if(4<=a && a<=6){
}
Apart from the obvious solution stated by others (if(4<=a && a<=6)), you can use commons-lang's IntRange:
Range range = new IntRange(4,6)
if (range.containsInteger(5)) {..}
It looks like a bit of an overkill, but depending on the situation (if it isn't as trivial) it can be very useful.
if(4 <= a && a <= 6) {
// do something
}
Of course, you could always write a function like this in some Util class:
class Util {
public static boolean inclusiveBetween(int num, int a, int b) {
return num >= a && num <= b;
}
}
and then you can do something like
if(Util.inclusiveBetween(someResourceIntensiveOpReturningInt(), 4, 6)) {
// do things
}
You can't, I don't think. What's wrong with
int a = 5;
if(a >= 4 && a <= 6) {
}
? If you need to compare many different variables, put them in an array and sort the array, then compare the arrays.
You can do this. Its ugly, but can be very slightly faster.
int a = 5;
if(a - Integer.MIN_VALUE - 4 <= 2 - Integer.MIN_VALUE) {
}
This exploits the use of underflow to turn two comparisons into one. This can save about 1-2 nano-seconds. However, in some usecases it can cost the same amount, so only try it if you are trying to micro-tune a loop.
Related
I am a newbie to recursion and I am still learning it, so please tolerate my poor logic if it is bad. I have this function which has 5 parameters a,b,c,x,y. so what I essentially want to do is take an element out of either of these variables and add it to the other to finally get x , y. I want to try out this by myself and I have nearly done it, only i wanted to ask if there's any way i could get out of this recursive call, once I get the answer as "YES".
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String in = sc.nextLine();
int[] input = new int[10];
for(int i=0; i < 10; i=i+2) {
input[i] = Integer.parseInt(String.valueOf(in.charAt(i)));
}
int A = input[0];
int B = input[2];
int C = input[4];
int X = input[6];
int Y = input[8];
persistent(A,B,C,X,Y);
}
private static void persistent(int a, int b, int c, int x, int y) {
if(a == 0 || b == 0 || c == 0) {
if((a == x && b == y) && (b == x && a == y)) {
System.out.println("YES");
}
else if((b == x && c == y) || (c == x && b == y)) {
System.out.println("YES");
}
else if((a == x && c == y) && (c == x && a == y)) {
System.out.println("YES");
}
else {
return;
}
}
persistent(a-1,b+1,c,x,y);
persistent(a-1,b,c+1,x,y);
persistent(a+1,b-1,c,x,y);
persistent(a,b-1,c+1,x,y);
persistent(a+1,b,c-1,x,y);
persistent(a,b+1,c-1,x,y);
}
Your code never does.
Recursive algorithms pretty much all boil down to this exact same style:
First, check if some edge case has been reached (generally, the very simplest case). In this case, return immediately - do not recurse. By tautology, if the answer is so easy you can just give it without needing to recurse, that defines 'edge case' / 'simple case'. There must be at least one such case, or a recursive algorithm cannot work.
Otherwise, provide your answer and feel free to employ as many recursive calls as you prefer, but every single last one of those calls must be simpler, defined by the idea that it is strictly closer to that simple case as mentioned in 1.
All state is conveyed via parameters. It is common to have a private helper method that does the actual work which has a bunch of extra parameters, and the public API that is a one-liner that calls the helper, providing initial values for those extra parameters. Only if you have no such state can you omit this one.
Your code isn't doing this. There is a simple case, which is if a or b or c is 0, but your 6 recursive calls are not clearly moving towards simplicity.
The fix is not obvious. Your algorithm cannot work as written and cannot be fixed without considerably rethinking it.
Hopefully the above will help you: Your recursive calls need to become simpler somehow, guaranteed. Right now it's not guaranteed: Yes, every call is moving one of the 3 numbers closer to the edge case (be 0), but there is no clear flow: If I call your code with, say, 3/4/5 as arguments, then it makes recurisve calls with 2/5/5, 2/4/6, etcetera. That first call (2/5/5) is not moving guaranteed closer to the edge case, because as part of its call stack, it'll be doing 3/4/5 again.
public static int divisor(int m, int n) {
if (m == 0 || n == 0) {
return m+n;
} else {
return divisor(n, m%n);
}
}
It's giving me wrong answers for some input(I don't know which as they don't reveal which input they use for test case) in the amazon.interviewstreet.com
Also why this implementation keeps giving me stackoverflow(again no idea for which inputs)
public static int divisor(int m, int n) {
if(m == 0 || n == 0) {
return m+n;
} else if (m > n) {
return divisor(n, m%n);
} else {
return divisor(m, n%m);
}
}
Please let me know what am I missing. I'm new to programming and am still a beginner.
I think first one is a code for a programming contest. If so be careful with your data types. May be 'int' is not enough to hold the inputs. Try 'long' instead.
(and this will work only if your algorithm is correct.)
I think
return(m, n%m);
should be
return divisor(m, n%m);
Maybe invalid handling of negative values of n and m?
Read e.g. this: Best way to make Java's modulus behave like it should with negative numbers?
for the second part what is
return(m, n%m);
Is this code get compiled ?
use :
public static int divisor(int m, int n) {
if(m == 0 || n == 0)
return m+n;
else if(m>n)
return divisor(n, m%n);
else
return divisor(m, n%m);}
First,
return(m, n%m)
definitely does not compile, I suppose it was meant to be
return divisor(m, n%m);
Second, I guess what is wrong in the second snippet is handling of negative numbers.
Because A and B have the same GCD as -A and -B, I would add
m = Math.abs(m);
n = Math.abs(n);
to the beginning of the method
For the second part :
Also why this implementation keeps giving me stackoverflow(again no idea for which inputs)?
Try this input set :
5
3 1 16 5 10
It will give you the stackoverflow error. For your given code in pastebin.
Why ?
If the input is '1' there will be this problem.
edit your code part like below and see the out put for input (1 1).
public static int divisor(int m, int n) {
System.out.println("### "+m+" "+n);
if (m == 0 || n == 0) {
return m + n;
} else if (m > n) {
return divisor(n, m % n);
} else {
return divisor(m, n % m);
}
}
in some point out put will be like this :
.
.
### 1 1134903170
### 1 0
### 1 1836311903
### 1 0
### 1 -1323752223
### -1323752223 1
### -1323752223 1
### -1323752223 1
.
.
because in your code the function calling is like below.
public static int divFib(int num) {
int i = 1, j = 2, temp;
while (divisor(num, j) == 1) {
temp = j;
j = j + i;
i = temp;
}
return j;
}
divisor(num, j) will be called like divisor(1, 2) then below part will execute
else {
return divisor(m, n % m);
}
the calling will be like divisor(1,0) because n%m = 2%1 =0
then '1' will be return as (m+n = 1).
then while (divisor(num, j) == 1){} will execute again and 'j' will be get increased. But 'num' is '1'. the same thing happens again and again. resulting 'j' to be a huge number and eventually it will assigned a negative number. (I think you know why its happening).
The thing is this will not ever stopped. so the stack will be overflowed due to huge number of function calls.
I think this is a quite clear explanation and if you have any doubt please ask.
(Sorry i mistakenly post the answer here.)
I have a function which checks, whether a bit in an int is set or not.
But I think there will be a much faster implementation, since this one is linear and can't be the most efficient one, although I know the int should be between 1 and 1024.
public static int getBitPos(final int n) {
if (Integer.bitCount(n) != 1)
return Constants.UNDEFINED;
else {
for (int i = 0; i < Integer.MAX_VALUE; ++i) {
if (testBit(n, i))
return i;
}
}
return Constants.UNDEFINED;
}
Where testBit is the following standard function:
public static boolean testBit(final int n, final int pos) {
int mask = 1 << pos;
return (n & mask) == mask;
}
But there mast be a faster way, isn't there? If I have the value 17 and I want to know if the 4th bit (n = 8) is set? There should be a faster way to check whether the bit for n=8 is set...
Hope you can help me...
EDIT 1:
Thanks for the support. The comments and answers brought me to my mistake. I was setting the values wrongly, which made it more complicated than needed. I was never good at bit shifting.
I set the value like this, if I wanted the second bit to be set:
value = 2;
If I wanted the 4th bit to be set too, I added the value according to the 4th bit:
value += 8;
So value was 10, and the 2nd and 4th bit were set. So I saved the numbers in my class, instead of the bit-positions (8 as value, instead of 4 for the 4th bit, ...).
After changing this, I could get rid of my unnecessary function, which was way over the top!
Thanks for all help!
Your code always returns the lowest bit that is 1, if there is only one. You can achieve the same by doing this:
int foo = whatever;
int lowestSetBit = Integer.numberOfTrailingZeros(foo) + 1;
Your code would be
public static int getBitPos(final int n) {
if (Integer.bitCount(n) == 1)
return Integer.numberOfTrailingZeros(n) + 1;
return Constants.UNDEFINED;
}
Is there an elegant way in java to check if an int is equal to, or 1 larger/smaller than a value.
For example, if I check x to be around 5. I want to return true on 4, 5 and 6, because 4 and 6 are just one away from 5.
Is there a build in function to do this? Or am I better off writing it like this?
int i = 5;
int j = 5;
if(i == j || i == j-1 || i == j+1)
{
//pass
}
//or
if(i >= j-1 && i <= j+1)
{
//also works
}
Of course the above code is ugly and hard to read. So is there a better way?
Find the absolute difference between them with Math.abs
private boolean close(int i, int j, int closeness){
return Math.abs(i-j) <= closeness;
}
Based on #GregS comment about overflowing if you give Math.abs a difference that will not fit into an integer you will get an overflow value
Math.abs(Integer.MIN_VALUE - Integer.MAX_VALUE) //gives 1
By casting one of the arguments to a long Math.abs will return a long meaning that the difference will be returned correctly
Math.abs((long) Integer.MIN_VALUE - Integer.MAX_VALUE) //gives 4294967295
So with this in mind the method will now look like:
private boolean close(int i, int j, long closeness){
return Math.abs((long)i-j) <= closeness;
}
use Math.abs(x-5) <= 1 as a simple test. However, elegant is in the eye of the beholder. Strive for clarity instead.
Note than in general, for something like Glitch's fine answer or even this, there are overflow conditions that must be analyzed and understood. For correctness over all possible ints you should cast the arguments to long and perform the comparison using longs.
public void moveRowItemToBottomIfAllowed(int r, int f) {
int i = rows[r].peek().getType();
int j = 0;
if (bottom[f].isEmpty()) {
for (int k = 0; k < 4; k++) {
if ((k == f) || (bottom[k].isEmpty()) || (bottom[k].peek().getType() != i)) {
continue;
}
j = 1;
}
if (j == 0) {
bottom[f].push(rows[r].pop());
}
} else if ((!bottom[f].isEmpty()) && (rankTrueFalse(rows[r].peek(), bottom[f].peek())) && (rows[r].peek().getType() == bottom[f].peek().getType())) {
bottom[f].push(rows[r].pop());
}
}
As I'm still learning java I've been putting together some rules for a game, I went through how to do it logically and came up with the above code which works correctly but it looks like a bit of a mess - is there any neater way or a more efficient way of writing this code? any pointers are much appreciated.
I would extract methods to make the code more readable. At first sight I would extract
the for loop, or probably the whole contents of the if block,
the expression from the 2nd long else if
Use descriptive names for your new methods (and for your variables too, for that matter). This makes a huge difference in readability.
I would recommend that you use more descriptive names for your variables. What is r? What is f? I'm guessing that f is some sort of numeric representation of the suit, since you compare it to k, which iterates over four values.
There might be more to say about the code overall, but the first step is to write the code in a self documenting manner.
There are bits of expressions which could be extracted into local variables: rows[r].peek() and bottom[f].peek() being the most obvious ones.
It looks like you are using j as a flag. Booleans are better for that, but you can return early instead of setting the condition that guards the rest of the processing, getting rid of j entirely.
You're double checking that bottom[f].isEmpty()) is false, and can use the already looked up i instead of repeating rows[r].peek().getType()
Both sides of your first condition, if they end up doing the processing, do the same processing, which you can write once:
public void moveRowItemToBottomIfAllowed(int r, int f) {
int i = rows[r].peek().getType();
if (bottom[f].isEmpty()) {
for (int k = 0; k < 4; k++) {
if (k == f) continue;
if (bottom[k].isEmpty()) continue;
if (bottom[k].peek().getType() == i) return;
}
} else {
if (!rankTrueFalse(rows[r].peek(), bottom[f].peek())) return;
if (bottom[f].peek().getType() != i) return;
}
bottom[f].push(rows[r].pop());
}
This code is then structured as a bunch of guards with early exits, followed by the processing.
The guards could then be extracted into their own method, leaving:
public void moveRowItemToBottomIfAllowed(int r, int f) {
if (moveIsAllowed(r,f)) bottom[f].push(rows[r].pop());
}