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

avec Java Discussion :

Chiffre Romain, convertir une chaîne de caractères en chiffre.


Sujet :

avec Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Technicien réseau
    Inscrit en
    Septembre 2015
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Technicien réseau
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Septembre 2015
    Messages : 50
    Par défaut Chiffre Romain, convertir une chaîne de caractères en chiffre.
    Bonjour

    Je n'arrive pas à trouver comment passez des chiffres Romain en Chiffre Arabe.

    Plus exactement lorsque mon utilisateur rentre des chiffres Romain je ne sais pas comment faire pour décortiquer sa ligne afin de dissocier les différents chiffres Romain pour pouvoir les convertir.

    Voici le code que j'ai pour l'instant :

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    import java.util.Scanner;
     
    class Romain {
     
        public static void main(String[] args) {
            Scanner clavier = new Scanner(System.in);
            int[] nombres = {1000, 500, 100, 50, 10, 5, 1 };
            String symboles = "MDCLXVI";
     
     
    String [] unit = {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
    String [] diz = {"X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
    String [] cent = {"C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
    String [] mil = {"M"};
    int n =0;
    String r;
    char M = 1000;
    char D = 500;
    char C = 100;
    char L = 50;
    char X = 10;
    char V = 5;
    char I = 1;
     
     
    // ROMAIN ==> ARAB
     
    System.out.print("Entrez un nombre en chiffres romains : ");
     
    	 r = clavier.nextLine();
    	 r.toUpperCase(); 	
     
     
     
    	 int longeur = r.length();
     
    	 for (int i = 0; i < longeur; i++) {
    	 int convert = r.charAt(longeur - (longeur-i));
    	 convert = r.charAt(i)+convert;
     
    	 System.out.println(convert);
    	 }
     
    	 System.out.println("Conversion impossible, nombre romain mal formé.");
    }
    }
    Je ne sais absolument pas si je suis partie sur la bonne piste, j'ai du mal avec les tableaux.

    Merci d'avance.

  2. #2
    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 : 56
    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
    Billets dans le blog
    2
    Par défaut
    Salut,

    La conversion romain vers int(base 10 arabique sous-entendu) est beaucoup plus simple que la conversion arabique vers romain : on n'a pas besoin des valeurs correspondants aux combinaisons (dugenre IX qui vaut 9, IV qui vaut 4, etc.).

    Il y a 2 règles, ou plutôt une avec une sorte d'exception :

    1. Chaque caractère de la chaîne d'entrée vaut une valeur, et il suffit d'ajouter toutes ces valeurs ; On peut le résoudre par une table de convrsion, ou tout simplement un switch :
      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
      28
      29
      public static int romanCharToInt(char c){
              final int number;
              switch(c) {
              case 'I':
              	number=1;
              	break;
              case 'V':
              	number=5;
              	break;
              case 'X':
              	number=10;
              	break;
              case 'L':
              	number=50;
              	break;
              case 'C':
              	number=100;
              	break;
              case 'D':
              	number=500;
              	break;
              case 'M':
              	number=1000;
              	break;
              default:
              	throw new IllegalStateException("Caractère inconnu: " + c);
              } 
              return number;
          }
      Il suffit donc de parcourir tous les caractères de la chaîne d'entrée et de sommer toutes les valeurs correspondantes.
    2. l'exception c'est les cas du type IV, IX, LX... c'est-à-dire lorsque la valeur d'un caractère est supérieure à la valeur du caractère précédent, alors on doit faire quelque chose de particulier.
      Prenons le cas du IV : si j'applique la règle 1, j'obtiens 1 + 5 = 6, alors qu'on devrait avoir 4. A noter que VI vaut bien 6.
      Prenons le cas du XL : si j'applique la règle 1, j'obtiens 60, alors que je devrais obtenir 40. A noter que LX vaut bien 60.
      Prenons le cas du XC : si j'applique la règle 1, j'obtiens 110, alors que je devrais obtenir 90. A noter que CX vaut bien 110.
      Qu'observe-t-on ? Que la différence entre le résultat obtenu et le résultat attendu est égal à 2 fois la valeur du caractère précédent celui qu'on traite. Il suffit donc, lorsque la valeur du caractère courant est supérieure à la valeur du caractère précédent, de retirer de la somme obtenue par la règle 1, le double de la valeur du caractère précédent.
      En résumé, il faut faire une boucle sur tous les caractères en entrée, faire la somme des valeurs correspondant, mémoriser la valeur correspondante du caractère courant pour l'itération suivante, et gérer la condition de l'exception à la règle.
    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.

  3. #3
    Membre averti
    Homme Profil pro
    Technicien réseau
    Inscrit en
    Septembre 2015
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Technicien réseau
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Septembre 2015
    Messages : 50
    Par défaut
    Merci pour la réponse, hélas pour moi je n'ai pas encore vu "switch" et "break", je dois résoudre ce problème en utilisant uniquement avec des branchements conditionnels, des itérations et des tableaux.
    Je me demandé si il était possible découper la ligne "string" entré par l'utilisateur caractères par caractères pour les placer dans un tableau et ainsi faire une correspondance avec les chiffres arabes.
    Si cela est possible comment puis-je faire cela?

    Une autre question mon code ci dessus affiche la valeur 120 si je rentre X ( et 88 pour x), pourquoi d'où provient elle?


    merci d'avance.

  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 : 56
    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
    Billets dans le blog
    2
    Par défaut
    Dans ce cas, au plus simple, il te faut une table de conversion des motifs caractéristiques. Une Map serait le mieux, mais si tu n'as pas encore vu les Maps, utilise 2 tableaux.

    Dans cette table, M vaut 1000, MM 2000, MMM 3000, MMMM 4000, C 100, CC 200, CCC 300, CD 400, D 500, DC 600, DCC 700 DCCC, 800, CM 900, etc... On a 31 motifs (9 pour les unités(1,2,3...8,9), 9 pour les dizaines (10, 20, 30...80,90), 9 pour les centaines, 4 pour les milliers (il y a les extensions bien sûr mais je ne pense pas que tu doives les traiter).




    Tu peux éventuellement construire les 2 tableaux par programme.

    Ensuite, tu parcours ta chaîne, et tu cherches si un des motifs correspond au début : tant que tu trouves un motif (qui existe) plus grand que celui trouvé précédemment, tu continues. Sinon, tu prends la valeur correspondant au motif, tu l'ajoutes à la somme jusque-là, et tu recommences, en prenant en compte le reste de la chaine.

    Exemple : MMMMCMLXXXIV (4984)
    On a un motif : M on le prend, et on continue
    On a un motif : MM on le prend, et on continue
    On a un motif : MMM ...
    On a MMMM ...
    On n'a pas MMMMC, donc on convertit MMMM = 4000, et on reprend sur CMLXXXIV
    On a C, OK
    On a CM, ok
    On n'a pas CML : on converti CM : 900 + 4000, et on reprend sur LXXXIV
    On a L
    On a LX
    On a LXX
    On a LXXX
    On n'a pas LXXXI, on converti LXXX : 80 + 4900, eton reprend sur IV...

    Pour faire ça, il te faut 2 index : un pour avancer dans la chaîne pour traiter chaque nouveau caractère, et un qui dit le début du motif en cours dans la chaîne.

    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
    int nombre=0; // pour calculer le résultat
    int last=0;
    for(int i=0; i<chaine.lenth; i++) { 
    // on test si motif existe dans la table
    if ( !existe(chaine.substring(last, i+1)) ) {
        // le motif existe pas, on prend le précédent
        if ( i<=last ) { 
            // il y a une erreur quelque part
            throw new IllegalArgumentException(chaine+" n'est pas un nombre romain");
        }
        else {
             String motif = chaine.substring(last,i);
             // on cherche la valeur de motif
             nombre += valeurDeMotif(motif);
             last=i; // on reprend d'ici
        }
    }
    // ici, il faut penser qu'on a encore la fin de la chaîne à traiter (chaine.substring(last))...
    }
    valeurMotif(String motif) correspond à chercher l'index de motif dans le premier tableau et de prend la valeur de l'index trouvé dans le second tableau (nos 2 tableaux qui constitue la table de correspondances). Si le motif n'est pas trouvé dans le tableau, faire throw new IllegalArgumentException(motif + " n'est pas un nombre romain");
    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
    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 : 56
    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
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par hoturi Voir le message
    Une autre question mon code ci dessus affiche la valeur 120 si je rentre X ( et 88 pour x), pourquoi d'où provient elle?
    Tu veux dire 88 pour X et 120 pour x, non ? Ce sont les valeurs de codage des caractères en mémoire (dans l'encodage utilisé par Java pour coder les caractères), respectivement 88 pour X et 120 pour x. Ça n'a pas beaucoup de sens de chercher à passer par ces valeurs pour convertir du romain en décimal, à moins qu'il y ait une formule, un truc, que je ne connais pas, mais j'en doute (la progression I,V,X,L,C,M est numériquement croissante, alors qu'elle ne suit pas l'ordre alphabétique, alors que la progression numérique des codes de caractères est croissante aussi). Il a peut-être un truc avec le modulo...
    Je n'ai pas parlé de la casse parce que ça me semblait évident : il faut tout passer en majuscule avant de chercher à convertir, par un toUpperCase().
    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.

  6. #6
    Membre averti
    Homme Profil pro
    Technicien réseau
    Inscrit en
    Septembre 2015
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Technicien réseau
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Septembre 2015
    Messages : 50
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    Tu veux dire 88 pour X et 120 pour x, non ? Ce sont les valeurs de codage des caractères en mémoire (dans l'encodage utilisé par Java pour coder les caractères), respectivement 88 pour X et 120 pour x. Ça n'a pas beaucoup de sens de chercher à passer par ces valeurs pour convertir du romain en décimal, à moins qu'il y ait une formule, un truc, que je ne connais pas, mais j'en doute (la progression I,V,X,L,C,M est numériquement croissante, alors qu'elle ne suit pas l'ordre alphabétique, alors que la progression numérique des codes de caractères est croissante aussi). Il a peut-être un truc avec le modulo...
    Je n'ai pas parlé de la casse parce que ça me semblait évident : il faut tout passer en majuscule avant de chercher à convertir, par un toUpperCase().
    Merci pour la réponse je ne savais a quoi elle correspondaient même en supprimant des lignes de codes. Je vais regarder plus amplement ton code afin de m'en inspirer, je pense avoir un début afin de m'aider à faire mon programme.

    C'est super sympa.

  7. #7
    Membre averti
    Homme Profil pro
    Technicien réseau
    Inscrit en
    Septembre 2015
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Technicien réseau
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Septembre 2015
    Messages : 50
    Par défaut
    Merci de ton aide Joel mais je ne comprend pas vraiment ton code il doit,y avoir des notions que je n'ai pas encore vu, je suis vraiment perdu sur cette histoire de tableau cela ne m'inspire pas (et je ne suis que sur l'exercice intermédiare, le suivant me fait déjà peur), une personne ma aidé pour le début du code voila son travail :

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    import java.util.Scanner;
     
    class Romain {
     
        public static void main(String[] args) {
            Scanner clavier = new Scanner(System.in);
            int[] nombres = {1000, 500, 100, 50, 10, 5, 1 };
            String symboles = "MDCLXVI";
     
            /*******************************************
             * Complétez le programme Ã* partir d'ici.
             *******************************************/
     
            int j=1;
            int tot=0;
            int count=0;
            int som [] =new int [20] ;
            String [] s = {"M","D","C","L","X","V","I" };
     
            System.out.println("Entrez un nombre en chiffres romains : ");
            String rom = clavier.nextLine();
            rom = rom.toUpperCase();
     
     
            //***************************************************************************** 
            for(int i=0;i<rom.length();i++){ //determiner les valeurs des symboles de rom  	
     
            for(int k=0;k<7;k++){
     
            if(rom.substring(i,j).equals(s[k])){ //pour tester tableau rom par rapport au s
     
            	// som [k] =nombres[k];
            tot=tot+nombres[k];
            count=count+1;} } 
            j++; }
     
            //********************* AFFICHAFE DES CALCULES ***************
            if(count==rom.length()){
            // for(int i=0;i<som.length;i++){tot=tot+som[i];}
            System.out.println("arabes("+rom+") = "+tot);} 
            else{
            System.out.println("Conversion impossible, nombre romain mal formé."); }
    Il reste encore les cas particulier a savoir comment traiter les soustractions et autres petites complications :

    -un symbole positionné avant un autre symbole de valeur plus forte se retranche de ce dernier (ex: «IX» = 10 (X) - 1 (I) = 9); les symboles «V», «L» et «D» ne peuvent pas être utilisés en tant qu'élément soustracteur;

    -on n'emploie jamais successivement quatre symboles identiques (ex: 90 s'écrit 100 (C) - 10 (X), soit «XC» et non pas «LXXXX» - ni «LXL», en vertu des règles précédentes), et en cas d'ambiguïté, la séquence la plus courte sera retenue (ex: 150 s'écrit 100 (C) + 50 (L), soit «CL» et non pas 200 (CC) - 50 (L), soit «LCC»).

    j'avais pensé commencer par faire une boucle pour voir les caractères inférieures a celui qui suit : (mal dit, dsl)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
      for(int i=0;i<rom.length();i++){
            char c1 = rom.charAt(0);
            char c2 = rom.charAt(0+count); 
     
            if (c1>c2) {
     
            }	
            count++;	        
            }
    Je ne sais pas ci cela peut vraiment me permettre d'y voir plus clair.

    J'ai lu tes réponses mais je ne comprend pas comment faire avec les 2 index.

    Merci d'avance.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 30/04/2008, 18h36
  2. Convertir une chaîne de caractère (saisie dans un textbox) en décimal
    Par sab_etudianteBTS dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 23/09/2007, 22h17
  3. Convertir une chaîne de caractères XML en Node
    Par Invité dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 20/07/2007, 15h06
  4. Réponses: 4
    Dernier message: 22/12/2006, 16h10
  5. Convertir une chaîne de caractères
    Par PedroBD dans le forum Langage
    Réponses: 3
    Dernier message: 13/11/2006, 18h25

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