Java 中的分数化简

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6618994/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 08:18:47  来源:igfitidea点击:

simplifying fractions in Java

javasimplificationrational-numbers

提问by Pari Sairam Mohan

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.

我的任务是培养一个理性的班级。如果 500 和 1000 是我的输入,那么 (?) 必须是我的输出。我自己写了一个程序来找到它。

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

回答by Matt

You need the GCD. Either use BigInteger like Nathan mentioned or if you can't, use your own.

你需要 GCD。要么像 Nathan 提到的那样使用 BigInteger,要么如果你不能,使用你自己的。

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.

然后你可以将每个数字除以 GCD,就像你在上面所做的那样。

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.

这会给你一个不正确的分数。如果您需要混合分数,那么您可以获得新数字。例如,如果你有 1500 和 500 的输入,你最终会得到 3/2 作为你的答案。也许你想要 1 1/2。所以你只需除以 3/2 得到 1,然后得到 3/2 的余数,它也是 1。分母将保持不变。

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

如果你不相信我这行得通,你可以查看 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.

你的算法很接近,但不完全正确。此外,如果您想找到 gcd,您可能应该创建一个新函数。只是让它更干净,更容易阅读。您也可以测试该功能。

回答by Pa?lo Ebermann

For reference, what you implemented is the original subtractiveEuclidean Algorithmto calculate the greatest common divisorof 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.

然后使用n1。Matt 的回答显示了相同算法的递归版本。

回答by Bohemian

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

回答by ncmathsadist

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

回答by Kenny Cason

I have a similar BigRationalclass I use. The GcdFunctionis makes use of BigInteger's gcdfunction:

我有一个类似的BigRational课程。在GcdFunction是利用了BigIntegergcd功能:

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

    }

}

BigRationalcontains a BigIntegernumerator and denominator. isInteger()returns true if the simplified ratio's denominator is equal to 1.

BigRational包含一个BigInteger分子和分母。isInteger()如果简化比率的分母等于 1,则返回 true。