simplifying fractions in Java

筅森魡賤 提交于 2019-12-18 04:30:15

问题


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);
    }  
}

回答1:


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"
}



回答2:


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.




回答3:


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.




回答4:


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
    }
}



回答5:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!