Greatest common divisor - java

I try to find the greatest common divisor for two integers. But I don't understand what is wrong with my code:
public class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int a = s.nextInt();
int b = s.nextInt();
while (a != 0 | b != 0) {
if (a >= b) {
a = a % b;
} else {
b = b % a;
}
}
if (a == 0) {
System.out.println(b);
} else {
System.out.println(a);
}
}
}

Just change
a != 0 | b != 0
to
a != 0 && b != 0
Because you version will be work even a or b equals 0.
But you need to exit from loop when one of them equals 0.
&& - better than & because in your case you don't need to check
right-hand operator if left equals 0

It is easier to calculate the GCD if we understand the core logic. Try to understand what we need to do, and how we are going to do it before implementing the program.
What we are trying to find is the greatest number that divides both a and b.
So the question arises that how we are going to do it. We do a loop just like you did, but for this case, let's initially assume that a is greater than b.
The first step is to start the loop, while the calculation is not finished. The condition in our case is, we have to stop when any one of the two numbers becomes zero.
while (a != 0 && b != 0)
{
// Do the calculation here.
}
Now we have to write the calculation. We have assumed that a is greater than b or both are equal.
We keep on assigning the remainder of a divided by b to a.
while (a != 0 && b != 0)
{
a = a % b;
}
This makes the solution only half correct, we will have to deal with the other case, that is when b is greater than a. Why this happens is after some set of iterations, a will become less than b, and that will result in a being set to 0.
So let's do the same solution to the other case, when a is less than b.
while (a != 0 && b != 0)
{
if (a > b)
a = a % b;
else
b = b % a;
}
And this is what you wanted to achieve. The non-zero value will be the solution.
Let's just not stop here, and see why your current version does not work. You have had this in your condition.
Your condition is:
a != 0 | b != 0
Here, you are using bit-wise operator OR, between two boolean values, which comes to the following. Assume any of a and b is zero.
Case 1:
a != 0 => true
b != 0 => false
true | false => true
Case 2:
a != 0 => false
b != 0 => true
false | true => true
Therefore as you see in the above cases, it continues to loop until both becomes zero, and hence you will always be reported as the GCD is zero.
Hope this helps.

You probably need to implement the Eudidean's Algorithm (which is actually about the math) But here is an example of how does this alg works
private static int GCD(int a, int b)
{
int remainder = a % b;
while (remainder!= 0)
{
a = b;
b = remainder;
remainder = a % b;
}
return b;
}

Related

Java - While loop where all conditions must be false for it to exit

First of all is this possible? Second of all if it is how can it be done? Im trying to get the following code to work like that but even if one of the variables is 0 it exits the loop, it needs to be made that all 3 variables are less than 1 for it to exit
import java.util.Scanner;
public class BabyNim
{
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
int a, b, c, input;
String pile;
a = 3;
b = 3;
c = 3;
System.out.println("A: " + a + "\tB: " + b + "\tC: " + c);
while (a > 1 && b > 1 && c > 1)
{
System.out.print("Pile: ");
pile = keyboard.next();
System.out.print("How many to remove: ");
input = keyboard.nextInt();
switch (pile) {
case "a": {
a = a - input;
}case "b": {
b = b - input;
}case "c": {
c = c - input;
}
}
}
}
}
while (a >= 1 || b >= 1 || c >= 1)
it needs to be made that all 3 variables are less than 1 for it to exit
Like that, this is what is needed so that it exits, right?
a < 1 && b < 1 && c < 1
So, negate it:
!(a < 1 && b < 1 && c < 1)
Which can be written like this:
a >= 1 || b >= 1 || c >= 1
As others posted, you had a problem on your switch block that hadn't a break; after each condition. At least if that wasn't the intention.
The problem looks to be your switch: statement. If I remember correctly you need to put a 'break;' at the end of each case statement, otherwise you run the possibility of "falling through" other case criteria.
Also you have to examine the order of operations when using a boolean for a conditional. while( a > 1 && b > 1 && c > 1) will short circuit to false when a < 1. you may be looking for a mix of your condition and the one offered by #Andy Turner:
while(a>=1 && b>=1 && c >=1)

Why is my program giving an incorrect output in certain cases?

I have made an implementation of the Euclidean Algorithm in Java to find the Greatest Common Divisor (GCD) of two given numbers.
For the most part, my program works fine, I have tested it with a few random sets of numbers, although, I have found in one case (that I know of) that it's giving an incorrect output, which is for the following combination of numbers:
Enter integer a: 8965
Enter integer b: 55
The output of the program should be 55, although this is not the case. The out given is as follows:
gcd = 1
Execution time: 0.005747ms.
I'm not sure why this particular combination of numbers is causing a problem, as it works fine for other numbers, for example, here is the results for a different set of numbers:
Enter integer a: 15000
Enter integer b: 5325
gcd = 75
Execution time: 0.007389ms.
import java.util.Scanner;
public class EuclideanAlgorithm {
public static void main (String [] args) {
int a, b;
try(Scanner sc = new Scanner(System.in);) {
System.out.print("Enter integer a: ");
a = sc.nextInt();
System.out.print("Enter integer b: ");
b = sc.nextInt();
}
long start = System.nanoTime();
int answer = EuclideanAlgorithm(a, b);
long stop = System.nanoTime();
System.out.println("gcd = " + answer);
System.out.println("Execution time: " + ((stop - start) / 1e+6) + "ms.");
}
public EuclideanAlgorithm() {}; //Suppress default constructor
private static int EuclideanAlgorithm(int a, int b) {
if ( (a == 0) || (b == 0)) {
return 0;
}
if (b > a) {
int temp = a;
a = b;
b = temp;
}
int gcd = 1;
while(gcd != 0) {
if( (a % b) == 0) {
break;
}
gcd = a % b;
a = b;
b = gcd;
}
return gcd;
}
}
Whenever one of your numbers a, b is a multiple of the other, then your if condition will cause a break and 1 will be returned, which is incorrect. But the rest of the algorithm is incorrect also.
According to the pseudocode for the Euclidean Algorithm:
function gcd(a, b)
while b ≠ 0
t := b
b := a mod b
a := t
return a
You need to check if b is not 0, not the gcd. You'll need to modify your code to match this algorithm; your code is not currently matching this algorithm.
Because of the if condition inside this while loop
int gcd = 1;
while(gcd != 0) {
if( (a % b) == 0) {
break;
}
gcd = a % b;
a = b;
b = gcd;
}
So, in case a % b = 0 at the beginning -> result is always equaled to 1.
You need to handle that case separately.
int gcd = b;
while(a % b != 0){
gcd = a % b;
a = b;
b = gcd;
}
It's easy 55 divides 8965 that means you programm breaks in the first line and returns your initial value which is 1.
Instead something like this could help.
int gcd = 1;
if( (a % b) == 0) {
return b;
}
while(gcd != 0) {
if( (a % b) == 0) {
break;
}
gcd = a % b;
a = b;
b = gcd;
}

Not sure how to describe this line of code

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.

about Java BigInteger

I'm new to Java and just code a program with BigInteger.
public static void main(String[] args) {
BigInteger n = new BigInteger("5");
BigInteger i = new BigInteger("2");
while (lesserOrEqual(i,n) {
System.out.println("n.mod(i) = "+n.mod(i));
if (n.mod(i) == ZERO) {
n = n.divide(i);
}
else {
i.add(ONE);
}
System.out.println("n = "+n);
System.out.println("i = "+i);
}
public static boolean lesserOrEqual(BigInteger m, BigInteger n) `{
if (m.compareTo(n) == -1 || m.compareTo(n) == 0)
return true;
return false;
}
ZERO and ONE are defined of the type BigInteger 0, 1, respectively.
I want "i=2" to divide "n=5", if "n mod i == 0", else "i++", until "n" to be lesser or equal to "i".
I think the output must be
n.mod(i) = 1
n = 5
i = 3
n.mod(i) = 2
n = 5
i = 4
n.mod(i) = 1
n = 5
i = 5
n.mod(i) = 0
n = 1
i = 5
and with the equivalent code with primitive type int, I have the result as expected.
but this with BigInteger goes to infinite loop
n.mod(i) = 1
n = 5
i = 2
...
Does anyone know why it is so?
The BigInteger class represents integers as immutable objects.
There are two points here.
Don't use == to test if two BigIntegers are equal
To change the value of a BigInteger variable you must do i = i.add(ONE); and not just i.add(ONE);.
The reason not to use == to compare BigIntegers is because instead of checking for numerical equality you are checking that they are the same object in memory.
Consider with Strings.
String a = "a";
String b = "b";
String x = a + b;
String y = "ab";
In the above example x.equals(y) is true because they contain the same number of characters in exactly the same order. However, x == y is not true because they are different objects in memory.
The reason you need to to assign the result of arithmetic operations to a variable is because BigInteger is immutable. Thus arithmetic operations cannot change the value of the object it is operating on, but it can create a new BigInteger (which it returns). Which is why you must assign the result of the arithmetic operation to the variable you want it saved in.
As an aside a shortcut for your lesserThanOrEqual to is this.
boolean result = m.compareTo(n) <= 0;
Basically
m == n becomes m.compareTo(n) == 0
m != n becomes m.compareTo(n) != 0
m < n becomes m.compareTo(n) < 0
m > n becomes m.compareTo(n) > 0
m <= n becomes m.compareTo(n) <= 0
m >= n becomes m.compareTo(n) >= 0
both of the above answers are right. They are not telling you, however, that BigInteger instances are immutable. That means they don't change once set. That is why you need to always assign the result of a transformation...
You are doing this:
i.add(ONE);
But you should do this:
i = i.add(ONE);
You're not saving the result that gets returned from i.add(ONE). It's giving you a BigInteger object containing the desired value, but you're dropping it on the floor instead of assigning it to i.
i.add(ONE) has to be reassigned: i = i.add(ONE)

What's the syntax for mod in java

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.

Categories

Resources