IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

Problème d'affectation de variable dans une boucle


Sujet :

Java

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2013
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2013
    Messages : 3
    Points : 5
    Points
    5
    Par défaut Problème d'affectation de variable dans une boucle
    Bonjour,

    Je débute en Java. Dans un cours, je dois créer un programme qui génère un nombre aléatoire entre 1 et 10 000. Chacun des chiffres de ce nombre doivent être en ordre croissant lorsqu'on les lit de gauche à droite. Si ce n'est pas le cas, le programme doit généré un autre nombre, jusqu'à ce que la condition précédente soit vraie.

    Jusqu'à présent, mon programme est capable de décortiquer chaque chiffres et de tous les mettre dans une variable différente sans problème. Il les affiche et les résultats sont bons. Cependant, le problème survient lorsque je tente de créer la condition de la boucle ( (c1 < c2) && (c2<c3) && (c3<c4) && (c4<c5) )

    J'arrive à aucun résultat ou le programme entre dans une boucle infini. Voilà le code. Merci à celui ou celle qui saura répondre !

    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    double c1=0, c2=0, c3=0, c4=0, c5=0, nb=0;
             double i=0, i2=0, i3=0, i4=0, i5=0;
             double d1=0, d2=0, d3=0, d4=0, d5=0;
     
     
     
             do {
     
                 entierAleatoire9 = rnd.nextInt(10001);
                 System.out.println("L'entier généré est : " +entierAleatoire9);
                 nb = entierAleatoire9;
                 c1 = (nb/10000);
     
                 i = new Double(c1).intValue();
                 d1 = c1 - (new Double (i).doubleValue());
                 //System.out.println("décimale 1 = " +d1);
     
                 c1 = (int)d1;
     
                 i2 = new Double(c1).intValue();
                 d2 = (d1*10) - (new Double (i2*10).doubleValue());
                 //System.out.println("décimale 2 = " +d2);
     
                 c2 =(int)d2;
     
                 i3 = new Double(c2).intValue();
                 d3 = (d2*10) - (new Double (i3*10).doubleValue());
                 //System.out.println("décimale 3 = " +d3);
     
                 c3 =(int)d3;
     
                 i4 = new Double(c3).intValue();
                 d4 = (d3*10) - (new Double(i4*10).doubleValue());
                 //System.out.println("décimale 4 = " +d4);
     
                 c4 =(int)d4;
     
                 i5 = new Double(c4).intValue();
                 d5 = Math.rint((d4*10) - (new Double (i5*10).doubleValue()));
                 //System.out.println("décimale 5 = " +d5);
     
                 c5 = (int)d5;
     
     
             System.out.println("Les chiffres en ordres sont : " +c1 +"  " +c2+"  " +c3+"  " +c4+"  " +c5);  // Tout est parfait ici
     
             } while ((c1<=c2) && (c2<=c3) && (c3<=c4) && (c4<=c5)) ;    // Et tout va mal là !

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 47
    Points : 50
    Points
    50
    Par défaut
    Citation Envoyé par gabbf29 Voir le message
    Bonjour,

    Je débute en Java. Dans un cours, je dois créer un programme qui génère un nombre aléatoire entre 1 et 10 000. Chacun des chiffres de ce nombre doivent être en ordre croissant lorsqu'on les lit de gauche à droite. Si ce n'est pas le cas, le programme doit généré un autre nombre, jusqu'à ce que la condition précédente soit vraie.

    Jusqu'à présent, mon programme est capable de décortiquer chaque chiffres et de tous les mettre dans une variable différente sans problème. Il les affiche et les résultats sont bons. Cependant, le problème survient lorsque je tente de créer la condition de la boucle ( (c1 < c2) && (c2<c3) && (c3<c4) && (c4<c5) )

    J'arrive à aucun résultat ou le programme entre dans une boucle infini. Voilà le code. Merci à celui ou celle qui saura répondre !

    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    double c1=0, c2=0, c3=0, c4=0, c5=0, nb=0;
             double i=0, i2=0, i3=0, i4=0, i5=0;
             double d1=0, d2=0, d3=0, d4=0, d5=0;
     
     
     
             do {
     
                 entierAleatoire9 = rnd.nextInt(10001);
                 System.out.println("L'entier généré est : " +entierAleatoire9);
                 nb = entierAleatoire9;
                 c1 = (nb/10000);
     
                 i = new Double(c1).intValue();
                 d1 = c1 - (new Double (i).doubleValue());
                 //System.out.println("décimale 1 = " +d1);
     
                 c1 = (int)d1;
     
                 i2 = new Double(c1).intValue();
                 d2 = (d1*10) - (new Double (i2*10).doubleValue());
                 //System.out.println("décimale 2 = " +d2);
     
                 c2 =(int)d2;
     
                 i3 = new Double(c2).intValue();
                 d3 = (d2*10) - (new Double (i3*10).doubleValue());
                 //System.out.println("décimale 3 = " +d3);
     
                 c3 =(int)d3;
     
                 i4 = new Double(c3).intValue();
                 d4 = (d3*10) - (new Double(i4*10).doubleValue());
                 //System.out.println("décimale 4 = " +d4);
     
                 c4 =(int)d4;
     
                 i5 = new Double(c4).intValue();
                 d5 = Math.rint((d4*10) - (new Double (i5*10).doubleValue()));
                 //System.out.println("décimale 5 = " +d5);
     
                 c5 = (int)d5;
     
     
             System.out.println("Les chiffres en ordres sont : " +c1 +"  " +c2+"  " +c3+"  " +c4+"  " +c5);  // Tout est parfait ici
     
             } while ((c1<=c2) && (c2<=c3) && (c3<=c4) && (c4<=c5)) ;    // Et tout va mal là !
    Le problème viens du fait que la sortie de boucle c'est "si condition est false"
    donc avec (c1<=c2) && (c2<=c3) && (c3<=c4) && (c4<=c5) on sort de la boucle dès que l'une des conditions voulues est fausse. Il faut donc plutôt utiliser : !(c1<=c2 && c2<=c3 && c3<=c4 && c4<=c5)

    Rq: l'algorithme serait plus "élégant" en travaillant avec des int vus l'intervalle des valeurs.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int valeur = (int)(Math.random() * 10000);
    int a=0,b=0,c=0,d=0,e=0;
    int valeur = (int) (Math.random() * 10000);
     
    a = valeur /10000;
    b = (valeur - 10000 * a) / 1000;
    c = (valeur - 10000 * a - 1000 * b) / 100;
    d = (valeur - 10000 * a - 1000 * b - 100 * c) / 10;
    e = valeur - 10000 * a - 1000 * b - 100 * c - 10 * d;

    il y a aussi la solution de tirer un nombre entre 0 et 9 compris. le numéro suivant devra être aussi supérieur ou égale au précédant en faisant une petite boucle dans une méthode genre :
    int numeroSuivant(int numeroPrecedant)

  3. #3
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    ouais enfin, avec le modulo on se casse pas la nenette et c'est encore plus lisible hein
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Random r= new Random();
    int valeur = r.nextInt(10001);
     
    int a = valeur /10000;
    int b = (valeur %10000) / 1000;
    int c = (valeur %1000) / 100;
    int d = (valeur %100) / 10;
    int e = valeur %10;

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Au final, la fonction de génération devient donc (sur la base de la solution de @tchize_)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    private static Random random = new Random();
    public static int genere() {
     
       while(true) { 
          int valeur = 1 + random.nextInt(10000); // nombre entre 1 et 10000 inclus
          int a = valeur /10000;
          int b = (valeur %10000) / 1000;
          if ( a!=0 && b<=a ) continue;
          int c = (valeur %1000) / 100;
          if ( b!=0 && c<=b ) continue;
          int d = (valeur %100) / 10;
          if ( c!=0 && d<=c ) continue;
          int e = valeur %10;  
          if ( d!=0 && e<=d ) continue;
          return valeur;
       }
     
    }
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Membre éclairé Avatar de JoeChip
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2008
    Messages : 536
    Points : 803
    Points
    803
    Par défaut
    A mon nain blavi :
    - le "while(true)" et les "continue", c'est forcément pas terrible d'un point de vue sémantique... Il faut toujours éviter ce genre de trucs, sauf si la performance est cruciale,ce qui n'est pas le cas ici. break et continue sont déstructurants, en général, donc sont toujours un signe qu'il faut regarder de plus près.
    - Même si c'était le cas, on pourrait optimiser d'autres choses avant.

    Donc, j'ai refactorisé à ma sauce, en mélangeant une meilleur sémantique et dans la boucle une meilleure optimisation (et accessoirement en passant tout en anglais):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    private static Random random = new Random();
    public static int generate() {
       boolean notFound;
       do { 
          notFound = false;
          int value = 1 + random.nextInt(10000);
          int a = value /10000;
          int b = (value %10000) / 1000;
          if ( a!=0 && b<=a ) notFound = true;
          int a = value /1000;
          int b = (value %1000) / 100;
          int a = value /100;
          int b = (value %100) / 10;
          if ( a!=0 && b<=a ) notFound = true;
          int a = value /10;
          int b = (value %10);
          if ( b!=0 && a<=b ) notFound = true;
       }while (notFound);
       return value;
     
    }
    Mouais, pas terrible : on parcourt toute la boucle même quand on sait que la valeur ne correspondra pas. en plus ya toutes ces lignes qui n'arrêtent pas de se répéter ou presque, agaçant ça, en plus tous ces "a" et ces "b" qui intervertissent leur rôle c'est pas clair.
    On peut toujours déjà imbriquer les "if" si on veut améliorer la perf sans trop endommager la sémantique, même s'il est vrai que c'est pas terrible non plus, je préfère ça aux "continue". ... donc on commence par mettre ce qui se répète dans une fonction, puis on voit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    private static Random random = new Random();
    public static int generate() {
          boolean notGood(int value, int factor){
             int a = value/factor;
             int b = value %factor / (factor / 10) 
             return ( a!=0 && b<=a );
          }
       boolean notFound;
       do { 
          notFound = false;
          value = 1 + random.nextInt(10000);
          if notGood(value,10000) notFound = true;
          else if notGood(value,1000) notFound = true;
          else if notGood(value,100) notFound = true;
          else if notGood(value,10) notFound = true;
       }while (notFound);
    return value;
    Bon, on commence à voir clair ; maintenant il y a visiblement une boucle for pour générer les facteurs de 10... En en plus b est à lecture unique, dont plus ou moins inutile, et le "!=0" n'est utile que la première fois, donc a est aussi à usage unique, donc on se retrouve avec (erreurs de syntaxe corrigées, désolé je fais plutôt du Python ces temps-ci) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
        private static Random random = new Random();
        static boolean notGood(int value, int factor){
            return (((10 * (value%factor)) / factor)<=(value/factor));
        }
        public static int generate() {
           final int [] factors = {10000, 1000, 100, 10};
           boolean notFound;
           int value;
           do { 
              notFound = false;
              value = 1 + random.nextInt(10000);
              if (value>12344)   // 12345 est le premier nombre obéissant à la condition
              for (int factor : factors)
                  if (notGood(value,factor)) notFound = true;
           }while (notFound);
           return value;
        }
    Là ça commence à être cool, lisible, compact, pas un mot de trop... Je n'exclus pas l'un ou l'autre bug dans ma refactorisation, et il y a peut-être trop de parenthèses dans la fonction, mais c'est le matin et on n'est jamais trop prudent. Et il est vrai qu'on peut préférer, pour la clarté de lecture, la version avec "a" et "b" (moi en général j'hésite, ça dépend de ce que je recherche comme perfs, par exemple). On continue de parcourir toute la boucle même quand on sait que ça ne sera pas bon, mais ça peut ne pas être important en terme de perfs, et ça peut même être utile de travailler à temps relativement constant. Ya encore moyen d'adapter, je ne dis pas que ce dernier code est le meilleur, hein.
    Sans danger si utilisé conformément au mode d'emploi.

    (anciennement BenWillard, enfin moins anciennement que ... enfin bon c'est une longue histoire... Un genre de voyage dans le temps...)

  6. #6
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par JoeChip Voir le message
    - le "while(true)" et les "continue", c'est forcément pas terrible d'un point de vue sémantique...
    Il faut toujours éviter ce genre de trucs, sauf si la performance est cruciale,ce qui n'est pas le cas ici.

    ...
    d'adapter, je ne dis pas que ce dernier code est le meilleur, hein.
    Mouais, je ne débaterai pas ça ici. Pour moi c'est une question de point de vue justement, et pas vraiment sémantique.

    Après, sans chercher à savoir quelle solution est la meilleure sémantiquement, ou techniquement, ou du point de vue des performances, et sans évoquer les erreurs de syntaxes dans tous les sens (oups si finalement), je ne trouve pas qu'une boucle est forcément plus compréhensible (j'ai pensé à cette solution). Disons qu'une telle solution permettrait éventuellement plus facilement d'écrire une fonction plus générique, permettant de générer des nombres entre bornes quelconques.

    Enfin, si l'aspect performance n'est pas crucial, pourquoi tester le cas 12345 ?
    D'autant plus que tous les nombres <= 12344 étant tirés 9876 serait tiré, alors qu'il ne vérifie pas les conditions.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  7. #7
    Membre éclairé Avatar de JoeChip
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2008
    Messages : 536
    Points : 803
    Points
    803
    Par défaut
    Sémantiquement, ça veut dire "du point de vue du sens des mots".
    Un "while(true)" ça veut dire "ici, boucle infinie", et on sait que c'est faux, donc pourquoi ne pas utiliser la condition de sortie ? Je ne comprend pas ça. Si c'est pour les perfs, on peut toujours ajouter "break" après le "notFound = false" pour quitter la boucle for.

    Enfin, si l'aspect performance n'est pas crucial, pourquoi tester le cas 12345 ?
    Je ne comprend pas la question : on teste à partir de 12345 au lieu de se demander si le premier chiffre est 0. En principe on devrait donc dire " >9999", mais bon tant qu'on y est...
    D'autant plus que tous les nombres <= 12344 étant tiré 9876 serait tiré, alors qu'il ne vérifie pas les conditions.
    Là je ne comprend pas le raisonnement.

    Les erreurs de syntaxe, genre les ";" qui traînent et tout, ouais bon j'ai corrigé. Là je mélange un peu avec Python, bon. De toutes façons c'est pour expliquer le raisonnement, j'avais pas envie de passer sous Eclipse.
    Sans danger si utilisé conformément au mode d'emploi.

    (anciennement BenWillard, enfin moins anciennement que ... enfin bon c'est une longue histoire... Un genre de voyage dans le temps...)

  8. #8
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Dommage que tous ces codes échouent sur

    1
    12
    123
    1234

    Pourtant, tous respectent la condition de départ ^^

  9. #9
    Membre éclairé Avatar de JoeChip
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2008
    Messages : 536
    Points : 803
    Points
    803
    Par défaut
    Ah, j'ai cru qu'il fallait des nombres de 5 chiffres ni plus ni moins, vu qu'il est testé si a est zéro dans le premier code... Pour revenir à la sémantique, ce n'est pas une question de point de vue : while(true) est mauvais, puisqu'on peut toujours le remplacer par un "do ... while" ou un "while(!conditionDeSortie). La sémantique est la base profonde de la programmation : il faut écrire de façon à ce que ce soit facilement lisible, sans absurdités verbales, apparentes ou non. Plus ça ressemble à un texte "normal" mieux c'est... Les "trucs" style "while(true)" je ne vois pas ce que ça apporte, sans dec.
    Sans danger si utilisé conformément au mode d'emploi.

    (anciennement BenWillard, enfin moins anciennement que ... enfin bon c'est une longue histoire... Un genre de voyage dans le temps...)

  10. #10
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Dommage que tous ces codes échouent sur

    1
    12
    123
    1234

    Pourtant, tous respectent la condition de départ ^^

    mmm?!, pas le mien, ou est ce que je me trompe quelque part en faisant mes tests

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    public static void main(String[] args) {
     
    		for(int valeur: new int[]{1,12,123,1234} ) {
    			System.out.println(valeur +" vérifie " + verifie(valeur));	
    		}
     
    	}
     
    	public static boolean verifie(int valeur) {
     
    		boolean boucle=true;
    		while(boucle) {
    		  boucle=false; // veut tester le fonctionnement de la boucle et des continues, mais on veut pas boucler indéfiniment
    	      int a = valeur /10000;
    	      int b = (valeur %10000) / 1000;
    	      if ( a!=0 && b<=a ) continue;
    	      int c = (valeur %1000) / 100;
    	      if ( b!=0 && c<=b ) continue;
    	      int d = (valeur %100) / 10;
    	      if ( c!=0 && d<=c ) continue;
    	      int e = valeur %10;  
    	      if ( d!=0 && e<=d ) continue;
    	      return true;
    		}
    		return false;
     
    	}
    j'ai volonteraiment utiliser la même structure pour que le test soit valide...


    affiche :
    1 vérifie true
    12 vérifie true
    123 vérifie true
    1234 vérifie true
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  11. #11
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    autre exemple de sémantique pourrie, par exemple (déjà vu)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    for (int i=0;i<5;i++){
        switch(i){
           case 0:
              //....
              break;
           case 1:
              //....
              break;
           case 2:
              //....
              break;
           case 3:
              //....
              break;
           default:
              //....
              break;
        }
    }
    Tu dois naturellement te dire 'y a un truc qui cloche là'

  12. #12
    Membre éclairé Avatar de JoeChip
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2008
    Messages : 536
    Points : 803
    Points
    803
    Par défaut
    Oui... De toutes façons, dès que quelque chose se répète à peu de choses près, ou que c'est très indenté, ou qu'il y a un switch-case ou des tas de else if, il faut examiner de près : ça sent la refactorisation... sans parler des "for(int i...)" pour parcourir une liste, et où le i n'est jamais utilisé dans la boucle...
    Sans danger si utilisé conformément au mode d'emploi.

    (anciennement BenWillard, enfin moins anciennement que ... enfin bon c'est une longue histoire... Un genre de voyage dans le temps...)

  13. #13
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 311
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 311
    Points : 9 524
    Points
    9 524
    Billets dans le blog
    1
    Par défaut
    Pourquoi ne pas générer un chiffre aléatoire entre 0 et 9 4x en respectant la condition que le nouveau chiffre est supérieur au précédent (et qu'on n'a pas atteint 9) pour constituer ton nombre aléatoire compris entre 1 et 6789 ?
    (Je dis 6789 max et pas 10000 parce que vu la condition de chiffre croissant, on ne pourra pas dépasser ce nombre...)
    L'algorithme est plus simple je trouve... ça ressemblerait à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    char[] nbr = new char[4];
    int idx = 0;
    int i = 0;
    int j = 0;
    while (idx < 4)
    {
        while ((j = RandomUtils.nextInt(10)) <= i) {}
        nbr[idx++] = String.valueOf(j).charAt(0);
        i = j;
        if (i == 9) break;
    }
    System.out.println(nbr);
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  14. #14
    Membre confirmé Avatar de benratti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    471
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2004
    Messages : 471
    Points : 649
    Points
    649
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    Enfin, si l'aspect performance n'est pas crucial, pourquoi tester le cas 12345 ?
    d'accord avec toi, car faire ce type d'optimisation est totalement inutile alors que l'algo qui est implémenté est loin d'être performant. Générer directement un nombre répondant au critère est bien plus performant... en effet, entre 1 et 10000, il y a une très faible probabilité de tomber sur un nombre répondant au critère (~ 2% si je ne me trompe pas).

  15. #15
    Membre confirmé Avatar de benratti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    471
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2004
    Messages : 471
    Points : 649
    Points
    649
    Par défaut
    Citation Envoyé par OButterlin Voir le message
    Pourquoi ne pas générer un chiffre aléatoire entre 0 et 9 4x en respectant la condition que le nouveau chiffre est supérieur au précédent (et qu'on n'a pas atteint 9) pour constituer ton nombre aléatoire compris entre 1 et 6789 ?
    (Je dis 6789 max et pas 10000 parce que vu la condition de chiffre croissant, on ne pourra pas dépasser ce nombre...)
    L'algorithme est plus simple je trouve...
    Si on veut vraiment faire simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int[] tab = { 123,124,125,126,127,128,129,134,135,136,137,138,139,145,146,147,148,149,156,157,158,159,167,168,169,178,179,189,234,235,236,237,238,239,245,246,247,248,249,256,257,258,259,267,268,269,278,279,289,345,346,347,348,349,356,357,358,359,367,368,369,378,379,389,456,457,458,459,467,468,469,478,479,489,567,568,569,578,579,589,678,679,689,789,1234,1235,1236,1237,1238,1239,1245,1246,1247,1248,1249,1256,1257,1258,1259,1267,1268,1269,1278,1279,1289,1345,1346,1347,1348,1349,1356,1357,1358,1359,1367,1368,1369,1378,1379,1389,1456,1457,1458,1459,1467,1468,1469,1478,1479,1489,1567,1568,1569,1578,1579,1589,1678,1679,1689,1789,2345,2346,2347,2348,2349,2356,2357,2358,2359,2367,2368,2369,2378,2379,2389,2456,2457,2458,2459,2467,2468,2469,2478,2479,2489,2567,2568,2569,2578,2579,2589,2678,2679,2689,2789,3456,3457,3458,3459,3467,3468,3469,3478,3479,3489,3567,3568,3569,3578,3579,3589,3678,3679,3689,3789,4567,4568,4569,4578,4579,4589,4678,4679,4689,4789,5678,5679,5689,5789,6789 }; 
    Random random = new Random(new Date().getTime());
    System.out.println(tab[random.nextInt(tab.length)]);
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Random random = new Random(new Date().getTime()); 
     
     
    int i1 = random.nextInt(7);
    int i2 = i1 + random.nextInt(7 - i1) + 1;
    int i3 = i2 + random.nextInt(8 - i2) + 1;
    int i4 = i3 + random.nextInt(9 - i3) + 1;
    int valeur = i1 * 1000 + i2 * 100 + i3 * 10 + i4;

  16. #16
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 311
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 311
    Points : 9 524
    Points
    9 524
    Billets dans le blog
    1
    Par défaut
    Je pense qu'on n'a pas interprété "Chacun des chiffres de ce nombre doivent être en ordre croissant lorsqu'on les lit de gauche à droite" de la même façon...
    Du coup, pour moi, tes 2 propositions ne répondent pas à la demande...

    9 est une valeur possible si le premier chiffre tiré est un 9
    89 également si le premier chiffre tiré est un 8
    etc...
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  17. #17
    Membre confirmé Avatar de benratti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    471
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2004
    Messages : 471
    Points : 649
    Points
    649
    Par défaut
    Citation Envoyé par OButterlin Voir le message
    Je pense qu'on n'a pas interprété "Chacun des chiffres de ce nombre doivent être en ordre croissant lorsqu'on les lit de gauche à droite" de la même façon...
    Du coup, pour moi, tes 2 propositions ne répondent pas à la demande...

    9 est une valeur possible si le premier chiffre tiré est un 9
    89 également si le premier chiffre tiré est un 8
    etc...
    Je ne suis pas d'accord avec toi, mes solutions respectent les deux conditions de l'énoncé :

    1. le nombre tiré aléatoirement doit se trouver en 1 et 10000
    2. chacun des chiffres de ce nombre doivent être en ordre croissant lorsqu'on les lit de gauche à droite.

    Peux tu me sortir un cas où mes deux solutions sortiraient un nombre ne respectant pas ces deux conditions ?

    par contre, si tu souhaites que l'ensemble des nombres respectant ces deux conditions puissent être générés par mes deux solutions, alors effectivement il faut y apporter une correction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Random random = new Random(new Date().getTime());
     
    int i1 = random.nextInt(7);
    int i2 = i1 + random.nextInt((i1 == 0 ? 8 : 7) - i1) + (i1 == 0 ? 0 : 1);
    int i3 = i2 + random.nextInt((i2 == 0 ? 9 : 8) - i2) + (i2 == 0 ? 0 : 1);
    int i4 = i3 + random.nextInt((i3 == 0 ? 10 : 9) - i3) + (i3 == 0 ? 0 : 1);
    int valeur = i1 * 1000 + i2 * 100 + i3 * 10 + i4;
    et la seconde devient :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int[] tab = { 1,2,3,4,5,6,7,8,9,12,13,14,15,16,17,18,19,23,24,25,26,27,28,29,34,35,36,37,38,39,45,46,47,48,49,56,57,58,59,67,68,69,78,79,89,123,124,125,126,127,128,129,134,135,136,137,138,139,145,146,147,148,149,156,157,158,159,167,168,169,178,179,189,234,235,236,237,238,239,245,246,247,248,249,256,257,258,259,267,268,269,278,279,289,345,346,347,348,349,356,357,358,359,367,368,369,378,379,389,456,457,458,459,467,468,469,478,479,489,567,568,569,578,579,589,678,679,689,789,1234,1235,1236,1237,1238,1239,1245,1246,1247,1248,1249,1256,1257,1258,1259,1267,1268,1269,1278,1279,1289,1345,1346,1347,1348,1349,1356,1357,1358,1359,1367,1368,1369,1378,1379,1389,1456,1457,1458,1459,1467,1468,1469,1478,1479,1489,1567,1568,1569,1578,1579,1589,1678,1679,1689,1789,2345,2346,2347,2348,2349,2356,2357,2358,2359,2367,2368,2369,2378,2379,2389,2456,2457,2458,2459,2467,2468,2469,2478,2479,2489,2567,2568,2569,2578,2579,2589,2678,2679,2689,2789,3456,3457,3458,3459,3467,3468,3469,3478,3479,3489,3567,3568,3569,3578,3579,3589,3678,3679,3689,3789,4567,4568,4569,4578,4579,4589,4678,4679,4689,4789,5678,5679,5689,5789,6789 }; 
    Random random = new Random(new Date().getTime());
    int valeur = tab[random.nextInt(tab.length)]);

  18. #18
    Membre éclairé Avatar de Ceddoc
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2009
    Messages
    493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2009
    Messages : 493
    Points : 698
    Points
    698
    Par défaut
    Citation Envoyé par OButterlin Voir le message
    89 également si le premier chiffre tiré est un 8
    etc...
    Si le premier chiffre tiré est un 8 la condition est directement vrai pas la peine d'en tirer un deuxième. Sauf si dans son résumé d'énoncer il manque quelque chose du genre "je dois créer un programme qui génère un nombre aléatoire entre 1 et 10 000. Chacun des chiffres de ce nombre doivent être en ordre croissant lorsqu'on les lit de gauche à droite et ce nombre doit avoir au moins deux chiffres."


    Citation Envoyé par benratti Voir le message
    Je ne suis pas d'accord avec toi, mes solutions respectent les deux conditions de l'énoncé :

    1. le nombre tiré aléatoirement doit se trouver en 1 et 10000
    2. chacun des chiffres de ce nombre doivent être en ordre croissant lorsqu'on les lit de gauche à droite.

    Peux tu me sortir un cas où mes deux solutions sortiraient un nombre ne respectant pas ces deux conditions ?
    Tu ne respecte pas cette condition puisque le nombre n'est pas aléatoire il est contenu dans un tableau limité.

    Sinon tant qu'a faire tu ne met que "123" dans toutes les cases de ton tableau et tu fais un random sur l'index...

  19. #19
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par OButterlin Voir le message
    Pourquoi ne pas générer un chiffre aléatoire entre 0 et 9 4x en respectant la condition que le nouveau chiffre est supérieur au précédent (et qu'on n'a pas atteint 9)
    cette technique ne rends pas tous les nombres équiprobables. Les nombres petits seront privilégiés. Pour le faire, faisont le calculer avec 2 chiffres

    1,2,3,4,5,5,6,8,9 -> 1 chance sur 9



    Soit 8 choisi -> la seule solution est 89 -> une chance sur 9 (note que tu n'a rien pour générer "8")

    Soit 7 choisi -> Deux solution équiprobables 78, 79 -> A chance sur 18
    Soit 1 choisi -> 12 13 14 15 16 17 18 19 -> 8 possibilités -> 1 chance sur 72

    Donc déjà, 9 & 89 on chacun une chance sur 9 de sortir, 78 une chance sur 18 et 11 une chance sur 72 ....

    On ne joue pas comme ça avec les nombre aléatoires Si on veux faire ce genre de code, il faut appliquer la méthode suivantes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Soit N le nombre de combinaisons valables possible:
    Prendre un nombre i au hasard entre 0 et N
    Sortir la combinaison associée à ce nombre i
    Reste à se casser la tête pour l'implémentation des étapes 1 et 3 De ce coté là, benratti y a été comme un bourrin et en oubliant certaines combinaisons, mais ce serait une solution "performance" en terme CPU, mais pas en terme de temps de developpement et de lisibilité

  20. #20
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 311
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 311
    Points : 9 524
    Points
    9 524
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par benratti Voir le message
    Je ne suis pas d'accord avec toi, mes solutions respectent les deux conditions de l'énoncé :

    1. le nombre tiré aléatoirement doit se trouver en 1 et 10000
    2. chacun des chiffres de ce nombre doivent être en ordre croissant lorsqu'on les lit de gauche à droite.

    Peux tu me sortir un cas où mes deux solutions sortiraient un nombre ne respectant pas ces deux conditions ?
    9... par exemple...

    Ceci dit, le mien n'est pas au point non plus, il ne peut pas sortir 1, entre autres...
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

Discussions similaires

  1. [Batch] problème d'affectation de variable dans boucle imbriquée
    Par fred_04510 dans le forum Scripts/Batch
    Réponses: 2
    Dernier message: 04/02/2012, 08h30
  2. Mauvaise affectation de variable dans une boucle
    Par Isiker dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 08/10/2009, 00h42
  3. Réponses: 2
    Dernier message: 24/03/2009, 09h09
  4. [ANT] affectation de variables dans une boucle
    Par dino_xrc dans le forum ANT
    Réponses: 6
    Dernier message: 17/12/2007, 19h47
  5. [SQL] Affectation d'une variable dans une boucle
    Par monlam dans le forum PHP & Base de données
    Réponses: 9
    Dernier message: 25/10/2007, 14h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo