web-dev-qa-db-fra.com

simplifier les fractions en Java

Ma tâche est de développer une classe rationnelle. Si 500 et 1000 sont mes entrées, alors (½) doit être ma sortie .J'ai écrit un programme tout seul pour le trouver.

Existe-t-il un autre meilleur moyen de trouver la solution ou mon programme est-il déjà le meilleur?

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);
    }  
}
16
Pari Sairam Mohan

Question interessante. Voici un code exécutable qui le fait en quelques lignes:

/** @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"
}
36
Bohemian

Vous avez besoin du GCD. Utilisez BigInteger comme mentionné par Nathan ou, si vous ne le pouvez pas, utilisez le vôtre.

public int GCD(int a, int b){
   if (b==0) return a;
   return GCD(b,a%b);
}

Ensuite, vous pouvez diviser chaque nombre par le GCD, comme vous l'avez fait ci-dessus.

Cela vous donnera une fraction impropre. Si vous avez besoin d'une fraction mixte, vous pouvez obtenir les nouveaux numéros. Par exemple, si vous aviez 1500 et 500 entrées, vous obtiendrez 3/2 comme réponse. Peut-être que vous voulez 1 1/2. Donc, il suffit de diviser 3/2 et d'obtenir 1, puis le reste de 3/2 qui est également 1. Le dénominateur restera le même.

whole = x/y;
numerator x%y;
denominator = y;

Si vous ne me croyez pas que cela fonctionne, vous pouvez vérifier http://en.wikipedia.org/wiki/Euclidean_algorithm

Il se trouve que j'aime bien la fonction récursive parce qu'elle est propre et simple.

Votre algorithme est proche, mais pas tout à fait correct. En outre, vous devriez probablement créer une nouvelle fonction si vous voulez trouver le gcd. Le rend juste un peu plus propre et plus facile à lire. Vous pouvez également tester cette fonction.

11
Matt

Pour référence, ce que vous avez implémenté est le soustractif _ ​​ algorithme euclidien original pour calculer le plus grand commun diviseur de deux nombres.

Une version beaucoup plus rapide utilise le reste de la division entière, par exemple. % au lieu de - dans votre boucle:

while (n1 != 0 && n2 != 0){
  if(n1 > n2)
     n1 = n1 % n2;
  else
     n2 = n2 % n1;
}

... et assurez-vous d'utiliser celui qui n'est pas zéro.

Voici une version plus simple:

while(n1 != 0) {
   int old_n1 = n1;
   n1 = n2 % n1;
   n2 = old_n1;
}

puis utilisez n1. La réponse de Matt montre une version récursive du même algorithme.

5
Paŭlo Ebermann

Vous devriez faire de cette classe autre chose qu'un conteneur pour les méthodes statiques. Voici un squelette

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

J'ai une classe BigRational similaire que j'utilise. GcdFunction utilise la fonction BigInteger's gcd:

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 contient un BigInteger numérateur et dénominateur. isInteger() est vrai si le dénominateur du rapport simplifié est égal à 1.

0
Kenny Cason