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