It works fine but I'm just not sure how it works, could anyone explain it? Thanks
public static int gcd(int a, int b) {
return b==0 ? a : gcd(b, a%b);
}
You have a ternary operator (bool ? x : y). Such an operator will evaluate the statement before the question mark. If that evaluates to true, x will be chosen, y otherwise.
This means its logic is equivalent to this:
public static int gcd(int a, int b)
{
if (b == 0)
return a;
else
return gcd(b, a % b);
}
Next, a % b calculates the modulo of the two numbers, which is the remainder of the integer division a / b. Eg: 7 % 2 results in 1 and 14 % 5 yields 4.
Algorithm: http://en.wikipedia.org/wiki/Greatest_common_divisor
Syntax:
return b==0? a :gcd(b, a%b)
means
if(b==0)
return a;
else
return gcd(b, a%b);
It's a recursive static method, which calculated gcd of two numbers.
Consider this invocation of this method -
int gcd = gcd(12, 6);
Your method body becomes equivalent to -
return 6==0 ? 12 : gcd(6, 12 % 6);
since 6 is not equal to zero, gcd gets called again. This time, it's something like this -
return 0 == 0 ? 6 : gcd(6, 0 % 6);
and since 0 == 0 is true, 6 gets returned, which is the greatest common divisor between 12 and 6.
It is the implementation of the euclids algorithm to find the greatest divisor. It uses a recursion.
Related
I came across this codes for finding the GCD of an array of numbers from here
//Function to return gcd of a and b
static int gcd(int a, int b) {
if (a == 0) {
return b;
}
return gcd(b % a, a);
}
// Function to find gcd of array of
// numbers
static int findGCD(int arr[], int n) {
int result = arr[0];
for (int i = 1; i < n; i++) {
result = gcd(arr[i], result);
}
return result;
}
The method gcd uses a recursive call gcd(b % a, a). So how does this recursive call works? I know the basics of how a recursion works but I am a little confused on how the gcd method on this piece of code uses recursion. Can anyone please explain to me simply, how the gcd method works in this code?
Let's take two numbers 24 and 60, and you called the function as gcd(24, 60), then the function stack executes as follows,
gcd(24,60) => 60%24 = 12
gcd(24,12) => 12%24 = 12 (Switch happens)
gcd(12,24) => 24%12 = 0
gcd(0 ,12) => terminates
So switch that happens at step two is the important one because the call basically swaps two numbers, just like you do in an iterative way, think of it like shorthand way.
I could take the same example with 60 and 24 as the first call, then gcd(60,24) would execute as
gcd(60,24) => 24%60 = 24 (Switch happens)
gcd(24,60) => 60%24 = 12 and this follows the same pattern as the above
Here the switch happens because the functions send b%a to the next function as a and a to the function as b.
Given two numbers, 12 and 8:
gcd(12,8) calculates b%a = 12%8 = 4 and then calls gcd(4, 8). It does not return yet, because that last call is not completed yet.
gcd(4,8) calculates b%a = 8%4 = 0 and then calls gcd(0,4). That one does not return yet as well, because that call is active.
gcd(0,4) branches into the first if-statement and returns 4.
That defines the return value of gcd(4,8), so the pending call returns 4 as well.
That again defines the return value of gcd(12,8), so the final result is still 4.
The math behind it is also interesting.
I think the main question is: why can we reduce gcd(12,8) to gcd(4,8)?
We assume that there is any result g that can divide 12 without a remainder and 8 without a remainder.
We can split the 12 into g*n (4*3) and 8 into g*m (4*2).
Next, we can say 12-8 = gn-gm = g*(n-m) (4*(3-2)=4). Therefore g does not only divide 12 and 8 without remainder, but also 12-8 (4).
You can do that for even lower numbers: 12-8-8 = gn-gm-gm=g(n-m-m) (4*(3-2-2)=-4). And so on.
The same is true for larger numbers: 12+8 = gn+gm = g*(n+m) (4*(3+2)=20). And you can repeat that by adding 8 numerous times.
The smallest positive number you can get by this approch is 12%8, because you can subtract 8 from 12 for so many times until its remainder is left.
To help understand recursive methods it is often useful to place print statements in key locations so you can follow what is happening.
By calling the method with specifically chosen prime factors, it is easy to ensure a particular gcd.
In the example below, 3 is the only common factor so it will be the gcd of the two numbers.
public class RecursiveGCD {
public static void main(String[] args) {
System.out.println("GCD = " + gcd(2 * 3 * 4 * 4 * 5, 3 * 7 * 11));
}
public static int gcd(int a, int b) {
System.out.println("\nFinding gcd of a=" + a + " and b=" + b);
if (a == 0) {
System.out.println("a == 0 so returning b (gcd) = " + b);
return b;
}
System.out.println(
"Remainder non-zero, calling with gcd(b % a, a) = gcd(" + (b % a)
+ ", " + a + ").");
return gcd(b % a, a);
}
}
I was trying to use java's integer division, and it supposedly takes the floor. However, it rounds towards zero instead of the floor.
public class Main {
public static void main(String[] args) {
System.out.println(-1 / 100); // should be -1, but is 0
System.out.println(Math.floor(-1d/100d)); // correct
}
}
The problem is that I do not want to convert to a double/float because it needs to be efficient. I'm trying to solve this with a method, floorDivide(long a, long b). What I have is:
static long floorDivide(long a, long b) {
if (a < 0) {
// what do I put here?
}
return a / b;
}
How can I do this without a double/float?
floorDiv() from Java.Math that does exactly what you want.
static long floorDiv(long x, long y)
Returns the largest (closest to positive infinity) long value that is less than or equal to the algebraic quotient.
Take the absolute value, divide it, multiply it by -1.
Weird bug.
You can use
int i = (int) Math.round(doubleValToRound);
It will return a double value that you can cast into an int without lost of precission and without performance problems (casts haven't a great computational cost)
Also it's equivalent to
int a = (int) (doubleValToRound + 0.5);
//in your case
System.out.println((int) ((-1 / 100) + 0.5));
With this last one you won't have to enter into tedious and unnecesary "if" instructions. Like a good suit, its valid for every moment and has a higher portability for other languages.
This is ugly, but meets the requirement to not use a double/float. Really you should just cast it to a double.
The logic here is take the floor of a negative result from the integer division if it doesn't divide evenly.
static long floorDivide(long a, long b)
{
if(a % b != 0 && ((a < 0 && b > 0) || (a > 0 && b < 0)))
{
return (a / b - 1);
}
else
{
return (a / b);
}
}
Just divide the two integers. then add -1 to the result (in case the absolute value of both numerator and denominator are not same). For example -3/3 gives you -1, the right answer without adding -1 to the division.
Since a bit late, but you need to convert your parameters to long or double
int result = (int) Math.floor( (double) -1 / 5 );
// result == -1
This worked for me elegantly.
I would use floorDiv() for a general case, as Frank Harper suggested.
Note, however, that when the divisor is a power of 2, the division is often substituted by a right shift by an appropriate number of bits, i.e.
x / d
is the same as
x >> p
when p = 0,1,...,30 (or 0,1,...,62 for longs), d = 2p and x is non-negative. This is not only more effective than ordinary division but gives the right result (in mathematical sense) when x is negative.
I have to divide two numbers by just using the bitwise operators. My code is as follows:
public class Solution {
public int divide(int dividend, int divisor) {
int c = 0, sign = 0;
if (dividend < 0) {
dividend = negate(dividend);
sign^=1;
}
if (divisor < 0) {
divisor = negate(divisor);
sign^=1;
}
if ( divisor != 0){
while (dividend >= divisor){
dividend = sub(dividend, divisor);
c++;
}
}
if (sign == 1){
c = negate(c);
}
return c;
}
private int negate(int number){
return add(~number,1);
}
private int sub(int x, int y){
return add(x,negate(y));
}
private int add(int x, int y){
while ( y != 0){
int carry = x&y;
x = x^y;
y = carry << 1;
}
return x;
}
}
I am getting a time out exception while running the code :
Last executed input:
2147483647
1
I added an extra check in the code like this :
if (divisor == 1){
return dividend;
}
but then on running the code again, I am getting a Time out exception like this:
Last executed input:
2147483647
2
Can you help me where I am going wrong with the code?
Since you are using a naïve implementation of the arithmetical operations, I assume it just takes too long, since it has to do roughly 1 billion of subtractions, each of which is a loop of 16 iterations on average. So it'd be about 5 seconds on a 3GHz CPU, if every inner step took 1 cycle. But since it obviously takes more, especially considering it's in java, I'd say you can easily expect something like a 1 minute running time. Perhaps java has a timeout check for the environment you are running it in.
I have to admit I haven't thoroughly verified your code and assumed it worked correctly algorithm-wise.
Think of how long division works, the pen-and-paper method for division we've all learnt at school.
Of course we've learnt it in base 10, but is there any reason why the same algorithm wouldn't work in base 2?
No, in fact it's easier because when you're doing the division step for each digit, the result is simply 1 if the part of the dividend above the divisor is greater than or equal to the divisor, and 0 otherwise.
And shifting the divisor and the result come out of the box too.
This question already has answers here:
How to check if a number is a power of 2
(32 answers)
Closed 7 years ago.
public class test{
public static void main(String[] args) {
int a=536870912;
System.out.print((Math.log(a)/Math.log(2)));
}
}
536870912 is a number that is power of two, but the result is 29.000000000000004, could anybody explain this? Thanks.
If n is a power of 2, then its binary representation will start with 1 and will contain only 0s after it.
So, you can do:
String binary = Integer.toBinaryString(a);
Pattern powerOfTwoPattern = Pattern.compile("10*");
System.out.println(powerOfTwoPattern.matcher(binary).matches());
Anyway, if you number is not really huge (i.e. fits the int or long range), then you can follow the suggestions here
You can use below method:-
boolean isPowerOfTwo (int x)
{
while (((x % 2) == 0) && x > 1) /* While x is even and > 1 */
x /= 2;
return (x == 1);
}
Explanation:- Repeatedly divides x by 2. It divides until either the quotient becomes 1, in which case x is a power of two, or the quotient becomes odd before reaching 1, in which case x is not a power of two.
pseudo-code following, easily adapted to java
boolean is_power_of_two(int num)
{
int i = Math.ceil(Math.log(num)/Math.log(2.0));
/*while ( i >= 0 )
{
// note 1 is taken as power of 2, i.e 2 ^ 0
// chnage i > 0 above to avoid this
if ( num == (1 << i) ) return true;
i--;
}
return false;*/
// or even this, since i is initialised in maximum power of two that num can have
return (num == (1 << i)) || (num == (1 << (i-1)));
}
NOTE it also can be done with discrete logarithm in constant-time without compiling to string represenation etc, but needs a precomputed table of discrete logarithms for base 2 or even using binary manipulation as in https://stackoverflow.com/a/600306/3591273, these approaches are constant-time but use the default representation of machine int or long
As an example in pseudocode:
if ((a mod 2) == 0)
{
isEven = true;
}
else
{
isEven = false;
}
Instead of the modulo operator, which has slightly different semantics, for non-negative integers, you can use the remainder operator %. For your exact example:
if ((a % 2) == 0)
{
isEven = true;
}
else
{
isEven = false;
}
This can be simplified to a one-liner:
isEven = (a % 2) == 0;
Here is the representation of your pseudo-code in minimal Java code;
boolean isEven = a % 2 == 0;
I'll now break it down into its components. The modulus operator in Java is the percent character (%). Therefore taking an int % int returns another int. The double equals (==) operator is used to compare values, such as a pair of ints and returns a boolean. This is then assigned to the boolean variable 'isEven'. Based on operator precedence the modulus will be evaluated before the comparison.
Since everyone else already gave the answer, I'll add a bit of additional context. % the "modulus" operator is actually performing the remainder operation. The difference between mod and rem is subtle, but important.
(-1 mod 2) would normally give 1. More specifically given two integers, X and Y, the operation (X mod Y) tends to return a value in the range [0, Y). Said differently, the modulus of X and Y is always greater than or equal to zero, and less than Y.
Performing the same operation with the "%" or rem operator maintains the sign of the X value. If X is negative you get a result in the range (-Y, 0]. If X is positive you get a result in the range [0, Y).
Often this subtle distinction doesn't matter. Going back to your code question, though, there are multiple ways of solving for "evenness".
The first approach is good for beginners, because it is especially verbose.
// Option 1: Clearest way for beginners
boolean isEven;
if ((a % 2) == 0)
{
isEven = true
}
else
{
isEven = false
}
The second approach takes better advantage of the language, and leads to more succinct code. (Don't forget that the == operator returns a boolean.)
// Option 2: Clear, succinct, code
boolean isEven = ((a % 2) == 0);
The third approach is here for completeness, and uses the ternary operator. Although the ternary operator is often very useful, in this case I consider the second approach superior.
// Option 3: Ternary operator
boolean isEven = ((a % 2) == 0) ? true : false;
The fourth and final approach is to use knowledge of the binary representation of integers. If the least significant bit is 0 then the number is even. This can be checked using the bitwise-and operator (&). While this approach is the fastest (you are doing simple bit masking instead of division), it is perhaps a little advanced/complicated for a beginner.
// Option 4: Bitwise-and
boolean isEven = ((a & 1) == 0);
Here I used the bitwise-and operator, and represented it in the succinct form shown in option 2. Rewriting it in Option 1's form (and alternatively Option 3's) is left as an exercise to the reader. ;)
To get Java's % (REM) operation to work like MOD for negative X and positive Y values, you can use this method:
private int mod(int x, int y)
{
int result = x % y;
if (result < 0)
{
result += y;
}
return result;
}
or with the ternary operator (shorter, but not possible or less efficient in some situations):
private int mod(int x, int y)
{
int result = x % y;
return result < 0? result + y : result;
}
Java actually has no modulo operator the way C does. % in Java is a remainder operator. On positive integers, it works exactly like modulo, but it works differently on negative integers and, unlike modulo, can work with floating point numbers as well. Still, it's rare to use % on anything but positive integers, so if you want to call it a modulo, then feel free!
While it's possible to do a proper modulo by checking whether the value is negative and correct it if it is (the way many have suggested), there is a more compact solution.
(a % b + b) % b
This will first do the modulo, limiting the value to the -b -> +b range and then add b in order to ensure that the value is positive, letting the next modulo limit it to the 0 -> b range.
Note: If b is negative, the result will also be negative
The code runs much faster without using modulo:
public boolean isEven(int a){
return ( (a & 1) == 0 );
}
public boolean isOdd(int a){
return ( (a & 1) == 1 );
}
In Java it is the % operator:
15.17.3. Remainder Operator %
Note that there is also floorMod in the java.lang.Math class which will give a different result from % for arguments with different signs:
public static int floorMod(int x, int y)
As others have pointed out, the % (remainder) operator is not the same as the mathematical
mod modulus operation/function.
mod vs %
The x mod n function maps x to n in the range of [0,n).
Whereas the x % n operator maps x to n in the range of (-n,n).
In order to have a method to use the mathematical modulus operation and not
care about the sign in front of x one can use:
((x % n) + n) % n
Maybe this picture helps understand it better (I had a hard time wrapping my head around this first)
if (a % 2 == 0) {
} else {
}
you should examine the specification before using 'remainder' operator % :
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.17.3
// bad enough implementation of isEven method, for fun. so any worse?
boolean isEven(int num)
{
num %= 10;
if(num == 1)
return false;
else if(num == 0)
return true;
else
return isEven(num + 2);
}
isEven = isEven(a);
Also, mod can be used like this:
int a = 7;
b = a % 2;
b would equal 1. Because 7 % 2 = 1.
The remainder operator in Java is % and the modulo operator can be expressed as
public int mod(int i, int j)
{
int rem = i % j;
if (j < 0 && rem > 0)
{
return rem + j;
}
if (j > 0 && rem < 0)
{
return rem + j;
}
return rem;
}
In Java, the mod operation can be performed as such:
Math.floorMod(a, b)
Note:
The mod operation is different from the remainder operation. In Java, the remainder operation can be performed as such:
a % b
Another way is:
boolean isEven = false;
if((a % 2) == 0)
{
isEven = true;
}
But easiest way is still:
boolean isEven = (a % 2) == 0;
Like #Steve Kuo said.
The modulo operator is % (percent sign). To test for evenness or generally do modulo for a power of 2, you can also use & (the and operator) like isEven = !( a & 1 ).
An alternative to the code from #Cody:
Using the modulus operator:
bool isEven = (a % 2) == 0;
I think this is marginally better code than writing if/else, because there is less duplication & unused flexibility. It does require a bit more brain power to examine, but the good naming of isEven compensates.