Partage
  • Partager sur Facebook
  • Partager sur Twitter

probleme avec le factoriel!!!

    10 octobre 2011 à 23:56:14

    import java.util.Scanner;

    public class factoriel {

    /**
    * @param args
    */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    Scanner sc=new Scanner(System.in);
    System.out.println("donner le nombre ke vous voulez en avoir le factoriel");
    int n=sc.nextInt();
    long fact=1;
    for (int i=1; i<=n ; i++ )
    {
    fact=fact*i;
    }
    System.out.println("le factoriel est: "+ fact);
    }

    }



    voilà le code que j'ai réalisé!! le problème c'est que lors de l’exécution avec un nombre qui dépasse 20 le résultat affiché est totalement incorrect!! j'ai penser à changer le type long par double mais ça n'a servi à rien!! que dois-je faire svp??
    • Partager sur Facebook
    • Partager sur Twitter
      11 octobre 2011 à 0:12:54

      Dans un long en Java, tu peux mettre au maximum 9223372036854775807, et ben il se trouve 21! est plus grand...
      Il faut chercher du côté des BigInteger : http://download.oracle.com/javase/7/do [...] gInteger.html
      • Partager sur Facebook
      • Partager sur Twitter
        11 octobre 2011 à 0:13:49

        y'a pas une méthode qui fait déjà ça dans Math? Sinon pourquoi ne pas plutot faire une fonction récursive:
        public long fact(long value){
        if( value == 0 )
        return 1;
        else
        return fact( value - 1 ) * value; 
        }
        


        Je pense que c'est ça...A voir...
        • Partager sur Facebook
        • Partager sur Twitter
          11 octobre 2011 à 8:48:09

          Pour ma part j'utiliserai aussi un BogInteger.

          Mais pour la suite, merci de mettre ton code entre des balises codes (tu sélectionnes les lignes puis tu cliques sur la petite icône "</>" et tu choisis Java). De plus, faire une faute d'orthographe et une de grammaire dans la seule phrase de ton programme risque de décrédibiliser ton boulot...
          • Partager sur Facebook
          • Partager sur Twitter
          Lorsque l'on fait une recherche google, on tombe sur des forums qui nous disent de chercher sur google...
            13 octobre 2011 à 20:02:48

            Citation : WarriorDog

            y'a pas une méthode qui fait déjà ça dans Math? Sinon pourquoi ne pas plutot faire une fonction récursive:

            public long fact(long value){
            if( value == 0 )
            return 1;
            else
            return fact( value - 1 ) * value; 
            }
            



            Je pense que c'est ça...A voir...



            Et tu fais quoi si tu essayes de calculer la factorielle d'un trop gros nombre ?
            Un algo impératif en programmation est souvent mieux qu'un algo récursif... sauf s'il se fait "convertir", non ?

            Sinon, oui, la solution au problème est l'utilisation de BigInteger.

            EDIT: L'affichage bug avant... Quoique j'ai a un moment eu un StackOverflow avec la méthode récursive.

            import java.math.BigInteger;
            
            
            public class Main {
            	public static void main(String args[]){
            		BigInteger n = BigInteger.ONE;
            		for(int i = 1; i <= 1676; i++){
            			n = n.multiply(new BigInteger(Integer.toString(i)));
            		}
            		System.out.println(n.toString());
            		System.out.println(factorielle(new BigInteger("1676")).toString());
            	}
            	
            	public static BigInteger factorielle(BigInteger n){
            		return (n.toString().equals("1")) ? BigInteger.ONE : n.multiply(factorielle(n.subtract(BigInteger.ONE)));
            	}
            }
            
            • Partager sur Facebook
            • Partager sur Twitter
              14 octobre 2011 à 0:14:28

              Apparemment (j'ai lu ) que le récursif n'est pas super optimisé pour les PCs , j'ai pas réussi a demander a mon prof en cours faudrait voir .
              • Partager sur Facebook
              • Partager sur Twitter
              www.creationjeuxjava.fr - Unity3D - LibGDX - Tutoriels de Jeux vidéo !
                14 octobre 2011 à 1:16:46

                Citation : JohnCarmack

                Apparemment (j'ai lu ) que le récursif n'est pas super optimisé pour les PCs , j'ai pas réussi a demander a mon prof en cours faudrait voir .



                En fait, les fonctions qui ne sont pas tail-recursives et qui ne peuvent pas être optimisées comme telles par le compilateur (certaines peuvent l'être, tout dépend des compilos, et de l'agressivité des optimisations) peuvent poser des problèmes de stack overflow. En gros on empile trop d'appels récursifs sur la pile d'appels... Mais là, on n'est qu'à une vingtaine appels récursifs, ce qui est infime en quelque sorte.
                • Partager sur Facebook
                • Partager sur Twitter
                  14 octobre 2011 à 8:44:43

                  Citation : Someone

                  Un algo impératif en programmation est souvent mieux qu'un algo récursif... sauf s'il se fait "convertir", non ?


                  Oui bien sûr si ça ne compliques pas trop les choses, car faire l'algo non récursif du listage de fichier dans un dossier, eh bien ça doit etre bien galère (impossible non?)

                  Citation : Winnie007

                  Apparemment (j'ai lu ) que le récursif n'est pas super optimisé pour les PCs , j'ai pas réussi a demander a mon prof en cours faudrait voir .


                  Lorsque que tu appelles une fonction, on a ce qu'on appelle une pile de contexte, à chaque appel, tu sauvegardes un pointeur sur la fonction appelante. Sur des machines comme aujourd'hui, tu te poses pas trop la question du problème de la récursivité, les piles sont de grosses tailles... (Sauf en embarqué, où c'est l'inverse)
                  Sur le process, j'ai manqué de parler de détails important, mais en gros c'est ça :D

                  Un exemple:
                  return (n.toString().equals("1")) ? BigInteger.ONE : n.multiply(factorielle(n.subtract(BigInteger.ONE)));
                  


                  un code comme ça en embarqué c'est pas du tout conseillé (voir même partout), déjà que c'est une fonction récursive, alors si en plus tu fais appelles à d'autres fonctions pour soustraire et multiplié, eh bien tu multiplies par 5 la vitesse de remplissage de ta pile...
                  Faire des appels de fonction pour faire des grosses opérations, c'est quand même bien exagéré non?
                  • Partager sur Facebook
                  • Partager sur Twitter
                    14 octobre 2011 à 16:49:14

                    Non, mais ici, j'ai juste montré comment faire, mais j'ai clairement mis que je n'adhérais pas au code xD .
                    Mais je crois savoir que pour les BigIntegers, tu es obligé de passer par les méthodes du type...

                    Evidemment, pour de l'embarqué, je n'utiliserais pas ça, j'utiliserais avant tout les double(mais dépasse pas les 20!, comme dit avant), et surtout pas de fonction récursive.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      14 octobre 2011 à 18:36:28

                      Salut,

                      WarriorDog >> pour lister des fichiers en Itératif, il faut simplement explorer un arbre c'est assez simple en fait.

                      file f //la racine
                      pile p //pour simuler l'appel récursif
                      empiler(p, f)
                      tant que</souligne> p n'est pas vide
                         file tmp = pop(p)
                         afficher p
                         si tmp est un dossier
                             pour tout les fichier (et dossier) contenu dans tmp nommé x
                                 empiler x
                             fin pour tout
                          fin si
                      fin tant que


                      remplace la pile par une file et tu as une autre algo très connu pour parcourir un graphe.
                      Ces deux algos sont BFS et DFS.

                      Hedi
                      • Partager sur Facebook
                      • Partager sur Twitter
                        14 octobre 2011 à 19:20:34

                        Bah c'est une fonction récursive ton truc là, nan?
                        • Partager sur Facebook
                        • Partager sur Twitter
                          14 octobre 2011 à 23:31:24

                          Nan.

                          Puisqu'elle ne s'appelle pas elle même. D'ailleurs c'est même pas une fonction puisque ca ne retourne rien.

                          Hedi
                          • Partager sur Facebook
                          • Partager sur Twitter
                            15 octobre 2011 à 8:44:40

                            Citation : JohnCarmack

                            Apparemment (j'ai lu ) que le récursif n'est pas super optimisé pour les PCs , j'ai pas réussi a demander a mon prof en cours faudrait voir .



                            Comme ça a été dit, lorsqu'un programme appelle un sous-programme, il laisse des calculs en suspend, et donc doit stocker une adresse de retour. Par exemple si j'écris

                            foo = 4
                            bar = foo + sous_programme()
                            retourner bar


                            Ceci est une expérience.
                            Image utilisateur


                            alors on peut considérer que ce programme va être exécuté ligne par ligne (même une fois compilé), et, lors de l'appel de sous_programme(), l'adresse de l'instruction courante va devoir être mémorisée — c'est ce qui permettra de revenir faire les calculs après. C'est comme si on mettait en « pause » le programme, pour le reprendre après. Tout ceci prend un peu de place en mémoire, sur ce qu'on appelle la pile.

                            Cependant, il est faux de dire que, en général, la récursivité entraîne une explosion de la pile. Il existe une forme de fonction récursive qui peut être optimisée par les compilateurs assez intelligents de façon à ne plus consommer de place sur la pile — ces fonctions sont les « fonctions récursives terminales », ce sont celles qui ne laissent pas de calcul en suspend.

                            Maintenant, il est possible que Java ne réalise pas cette optimisation. Et dans tous les cas, on peut souvent dérécursifier des fonctions simples avec une pile explicite, comme l'a fait hedi07.
                            • Partager sur Facebook
                            • Partager sur Twitter
                              15 octobre 2011 à 10:07:24

                              En fait, on peut même toujours le faire. Dans le pire des cas il faut empiler tout le contexte d'exécution comme le ferai la machine lors d'un appel de fonction. C'est lourd mais c'est comme ca qu'on prouve que tout fonction récursive peut être écrite en itératif.

                              Hedi
                              • Partager sur Facebook
                              • Partager sur Twitter
                                15 octobre 2011 à 10:21:26

                                Pour moi ça c'est itératif:
                                pour tout les fichier (et dossier) contenu dans tmp nommé x
                                           empiler x
                                       fin pour tout


                                Citation : Someone

                                Cependant, il est faux de dire que, en général, la récursivité entraîne une explosion de la pile


                                J'ai l'impression de me sentir indirectement visé, si c'est le cas, je n'ai jamais dit ça...
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  15 octobre 2011 à 11:20:48

                                  Effectivement c'est itératif. Tu me reponds, ou tu te réponds a toi même ?
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    15 octobre 2011 à 12:55:45

                                    Je voulais dire récursif...
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      15 octobre 2011 à 14:12:30

                                      Un programme (fonction/algo) récursif est un programme qui s'appelle lui même. Mon code ne l'est donc pas puisque il ne s'appelle pas lui même.

                                      Un programme (fonction ou algo) itératif est à base de boucle.

                                      par exemple ces deux code font la même chose : ils somment les nombre de 1 à n.

                                      le premier itératif :

                                      fonction somme (n : entier positif) : entier
                                      a = 0
                                      pour i allant de 1 à n faire
                                      a = a + i
                                      fin pour
                                      retourne a
                                      fin fonction

                                      et le deuxième récursif :

                                      fonction somme(n : entier positif) : entier
                                      si n = 1
                                      retourne 1
                                      sinon
                                      retourne n + somme(n - 1)
                                      fin si
                                      fin fonction

                                      Il y a un tuto de Bluestorm sur ce site expliquant le récursivité.

                                      Hedi
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        16 octobre 2011 à 12:49:04

                                        Je suis désolé que tu es du perdre ton temps à expliquer quelque chose que je connais déjà...Je pense que le problème vient de la clareté de ton algo, manque de commentaire certainement ou nom mal choisi... Anyway, je ne suis pas du tout convaincu que tu puisses lister l'ensemble des fichiers d'un rép et des sous rép sans utiliser la récursivité. Il me semble évident d'utiliser la récursivité, j'ai même fait des recherches pour trouver un algo qui prouverai que tu dises vrai, mais sans succès (je suis de bonne foi :D )

                                        'fin bref,
                                        Tchuss
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          16 octobre 2011 à 14:36:35

                                          Des est un algorithme il faudrait que tu cherche une implémentation itérative. Celle que je t'ai donné l'ai. Je te ferai un Code java si j'ai le temps.

                                          Mais je ne comprends pas ce qui te fais dire que mon algo n'est pas itératif.
                                          Pourquoi ca ne te conviens pas.

                                          Et je te garanti que tout ce qu'on peut faire en itératif, on peut le faire en recursif et vice-versa.

                                          Hedi

                                          edit : voila le code. Il n'est pas récursif puisqu'il ne s'appelle pas lui même

                                          public static void main(String[] args) {
                                          	listDirIter();
                                                  listDirRec(new File("./"));
                                          }
                                          	
                                          public static void listDirIter() {
                                          	//on prends le repertoire courant comme base.
                                          	File f = new File("./");
                                          	//on créer une queue ou on va mettre les fichiers (et répertoires)
                                          	Queue<File> q = new LinkedList<File>();
                                          	//on ajoute la base de notre recherche (racine) 
                                          	q.add(f);
                                          	//puis tant que la queue n'est pas vide
                                          	while (!q.isEmpty()) {
                                          		// on prend le premier fichier de la queue et on ajoute ses enfants à la queue
                                          		File current = q.poll();
                                          		System.out.println(current);
                                          		if (current.isDirectory())
                                          			for (File contenu : current.listFiles())
                                          				q.add(contenu);
                                          	}
                                          }
                                          


                                          et voici une version récursive :

                                          public static void listDirRec(File f) {
                                                  System.out.println(f);
                                          	if (f.isDirectory())
                                          		for (File contenu : f.listFiles())
                                          			listDirRec(contenu);
                                          }
                                          


                                          Je ne sais pas si cela va marcher sous windows parce que j'ai mis "./" comme répertoire de base. ça devrait quand même.
                                          • Partager sur Facebook
                                          • Partager sur Twitter

                                          probleme avec le factoriel!!!

                                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                          • Editeur
                                          • Markdown