2016-05-06 1 views
0

Je veux créer une méthode qui trouve le produit de tous les entiers de 1 à n inclus. Voici mon code, mais il ne fait pas vraiment ce que je veux:Comment écrire une fonction factorielle?

public class MathUtil{ 

    int result; 

    public int product(int n){ 

     for (int i = 1; i <= n; i++){ 

      result = result * n * i; 

     } 

     return result; 

    } 

} 

Répondre

0

... En d'autres termes, n!

  • result aurait dû être initialisé à 1
  • result ne devrait pas être un champ, mais une variable locale
  • Ne pas multiplier par i * n, que par i
  • Pour calculer le produit de 1 à n, il pourrait être judicieux de valider que n >= 1

Comme ceci:

public int product(int n) { 
    if (n < 1) { 
     throw new IllegalArgumentException("n must be 1 or greater"); 
    } 

    int result = 1; 
    for (int i = 2; i <= n; i++) { 
     result *= i; 
    } 
    return result; 
} 

Gardez à l'esprit que cela rapidement débordement pour n > 12, ou si vous changez le type de retour à long, puis pour n > 20. (Merci @FredK pour avoir signalé!)

+0

Notez également que si le résultat est un int vous allez déborder pour tout n> 12, et si c'est long vous déborderez si n> 20 – FredK

+0

@FredK bon point, dûment noté, merci! – janos

3

Eh bien, result est initialisé à 0. Ensuite, dans une boucle, vous multipliez par quelque chose et définissez le résultat result. Comme nous le savons, tout ce qui est multiplié par zéro est zéro. Tenir compte result comme en cours d'initialisation 1

int result = 1; 

En outre, votre logique de multiplication est faux. Pourquoi multipliez-vous par n et i? Il suffit de multiplier par resulti

0

Ici, vous allez:

public class MathUtil 
{ 

    public int product(int n) 
    { 
     if (n < 3) return n; // no need to do any stuff if n is less then 3, 
         // since the result will be n... 
     int result = 1; // result must be here 
     for (int i = 2; i <= n; i++) // start from 2 
     { 
      result *= i; // don't need n here 
          // and you can make it shorter with *= 
     } 
     return result; 
    } 
} 

Note pour result; Disons que vous avez appelé cette méthode avec n = 3. result sera 6, mais il sera défini comme si sa variable de classe, donc lorsque vous appelez cette méthode avec n = 4 après que pour la même instance de cette classe, 146 sera retournée et result sera définie avec elle. C'est pourquoi vous devez faire en sorte que les méthodes soient variables, donc 1 chaque fois qu'une méthode est appelée, quelle que soit l'instance de cette classe. De plus, si vous en faites une variable de classe et que vous la définissez à 1 chaque fois que vous appelez cette méthode, elle peut toujours générer des problèmes de synchronisation si deux threads appellent cette méthode sur la même instance de cette classe. si vous ne planifiez pas une telle chose, c'est une bonne pratique).

0

Recursion fonctionne à merveille ici aussi ...

public int product(int someNum) { 
    if (someNum == 1) return 1; 
    return someNum * product(someNum-1); 
} 

Au format ternaire:

public int product(int someNum) { 
    return (someNum == 1) ? 1 : someNum * product(someNum -1); 
} 
+0

Notez, je ne vérifie pas que le nombre donné est supérieur à 1, ce qui conduira à une erreur si vous le faites de cette façon. –