My task is to develop a rational class. If 500 and 1000 are my inputs, then (½) must be my output. I have written a program on my own to find it.
Is there another best way to find the solution, or my program is already the best one?
public class Rational {
public static void main(String[] args){
int n1 = Integer.parseInt(args[0]);
int n2 = Integer.parseInt(args[1]);
int temp1 = n1;
int temp2 = n2;
while (n1 != n2){
if(n1 > n2)
n1 = n1 - n2;
else
n2 = n2 - n1;
}
int n3 = temp1 / n1 ;
int n4 = temp2 / n1 ;
System.out.print("\n Output :\n");
System.out.print(n3 + "/" + n4 + "\n\n" );
System.exit(0);
}
}
Interesting question. Here's some executable code that does it in just a couple of lines:
/** @return the greatest common denominator */
public static long gcm(long a, long b) {
return b == 0 ? a : gcm(b, a % b); // Not bad for one line of code :)
}
public static String asFraction(long a, long b) {
long gcm = gcm(a, b);
return (a / gcm) + "/" + (b / gcm);
}
public static void main(String[] args) {
System.out.println(asFraction(500, 1000)); // "1/2"
System.out.println(asFraction(17, 3)); // "17/3"
System.out.println(asFraction(462, 1071)); // "22/51"
}
You need the GCD. Either use BigInteger like Nathan mentioned or if you can't, use your own.
public int GCD(int a, int b){
if (b==0) return a;
return GCD(b,a%b);
}
Then you can divide each number by the GCD, like you have done above.
This will give you an improper fraction. If you need a mixed fraction then you can get the new numbers. Example if you had 1500 and 500 for inputs you would end up with 3/2 as your answer. Maybe you want 1 1/2. So you just divide 3/2 and get 1 and then get the remainder of 3/2 which is also 1. The denominator will stay the same.
whole = x/y;
numerator x%y;
denominator = y;
In case you don't believe me that this works, you can check out http://en.wikipedia.org/wiki/Euclidean_algorithm
I just happen to like the recursive function because it's clean and simple.
Your algorithm is close, but not exactly correct. Also, you should probably create a new function if you want to find the gcd. Just makes it a little cleaner and easier to read. You can also test that function as well.
For reference, what you implemented is the original subtractive Euclidean Algorithm to calculate the greatest common divisor of two numbers.
A lot faster version is using the remainder from integer division, e.g. %
instead of -
in your loop:
while (n1 != 0 && n2 != 0){
if(n1 > n2)
n1 = n1 % n2;
else
n2 = n2 % n1;
}
... and then make sure you will use the one which is not zero.
A more streamlined version would be this:
while(n1 != 0) {
int old_n1 = n1;
n1 = n2 % n1;
n2 = old_n1;
}
and then use n1. Matt's answer shows a recursive version of the same algorithm.
You should make this class something other than a container for static methods. Here is a skeleton
import java.math.BigInteger;
public class BigRational
{
private BigInteger num;
private BigInteger denom;
public BigRational(BigInteger _num, BigInteger _denom)
{
//put the negative on top
// reduce BigRational using the BigInteger gcd method
}
public BigRational()
{
this(BigInteger.ZERO, BigInteger.ONE);
}
public BigRational add(BigRational that)
{
// return this + that;
}
.
.
.
//etc
}
}
I have a similar BigRational
class I use. The GcdFunction
is makes use of BigInteger
's gcd
function:
public class GcdFunction implements BinaryFunction {
@Override
public BigRational apply(final BigRational left, final BigRational right) {
if (!(left.isInteger() && right.isInteger())) {
throw new EvaluationException("GCD can only be applied to integers");
}
return new BigRational(left.getNumerator().gcd((right.getNumerator())));
}
}
BigRational
contains a BigInteger
numerator and denominator. isInteger()
returns true if the simplified ratio's denominator is equal to 1.
来源:https://stackoverflow.com/questions/6618994/simplifying-fractions-in-java