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 :

Similarités entre chaînes de caractères


Sujet :

Java

  1. #1
    Futur Membre du Club
    Homme Profil pro
    comptable
    Inscrit en
    Juillet 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : comptable

    Informations forums :
    Inscription : Juillet 2015
    Messages : 8
    Points : 5
    Points
    5
    Par défaut Similarités entre chaînes de caractères
    Bonjour tout le monde,

    Je suis tout nouveau sur ce forum et je commence à apprendre java...

    J'ai besoin de votre aide pour terminer un programme que je n'arrive pas à faire fonctionner:

    Le programme
    Il demande à l'utilisateur d’entrer une combinaison de 5 chiffres (combinaison 1) puis d'entrer une autre combinaison de 5 chiffres (combinaison 2).
    La combinaison 2 doit correspondre à la combinaison 1. Donc, le programme affichera le nombre de bons chiffres.
    Exemples:
    1 /
    combinaison 1 = 17678
    combinaison 2 = 23733
    nombre de bons chiffres = 1 (même s'il y a deux 7 dans la combinaison 1, l'utilisateur n'en a entré qu'un seul)
    2 /
    combinaison 1 = 84452
    combinaison 2 = 13858
    nombre de bons chiffres = 2
    3/
    combinaison 1 = 64321
    combinaison 2 = 66666
    nombre de bons chiffres = 1

    Mon programme, QUI NE FONCTIONNE PAS, donne ça pour le moment :
    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
    public static void main (String[] params) {   
            int res = 0;
            String comb1;
            String comb2;
     
            System.out.println("combinaison 1 : ");
            comb1 = Clavier.lireString();
            System.out.println("combinaison 2 : ");
            comb2 = Clavier.lireString();
     
            for(int j = 0; j < comb1.length(); j++) {
                for(int i = 0; i < comb2.length(); i++) {
                    if (comb1.charAt(j) == comb2.charAt(i)) {
                        res = res + 1;
                        if(i < comb2.length()) {
                            comb2 = comb2.substring(i);                        
                        }else{
                            comb2= comb2.substring(i+1, comb2.length());                        
                        }
                        if(j < comb1.length()){
                            comb1 = comb1.substring(j);
                        }else{
                            comb1 = comb1.substring(j+1, comb1.length());                        
                        }
                    }
                    if(j < comb1.length()){                    
                        if(comb1.charAt(j) != comb2.charAt(i)){
                             j = j + 1;
                        }
                    }
                }
            }
            System.out.println(res);

  2. #2
    Membre expérimenté Avatar de Ivelios
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juillet 2008
    Messages
    1 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 031
    Points : 1 540
    Points
    1 540
    Par défaut
    Salut,

    Il faut éviter ( c'est même formellement interdit dans certaine culture ) de modifier la taille de la variable sur laquelle on itère dans un for.
    Pour revenir à ton problème. Tu souhaites qu'un char dans combi2 ne serve qu'une et une seul fois. Il suffit de le sauvegarder tout simplement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int res = 0;
    String comb1 = "64321";
    String comb2 = "66666";
    List<Integer> matchFoundIntoCom2 = new LinkedList();
    for(int j = 0; j < comb1.length(); j++) {
        for(int i = 0; i < comb2.length(); i++) {
            if (!matchFoundIntoCom2.contains(i) && comb1.charAt(j) == comb2.charAt(i)) {
                res++;
                matchFoundIntoCom2.add(i);
                break;// Match trouvé, on arrête d'itérer combi2 et on passe au prochain char de combi1
            }
        }
    }
    System.out.println(res);
    Y'a moyen d'optimiser encore le code ( via des regexp je pense ) mais c'est un meilleur piste que des substrings à droite et à gauche.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    comptable
    Inscrit en
    Juillet 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : comptable

    Informations forums :
    Inscription : Juillet 2015
    Messages : 8
    Points : 5
    Points
    5
    Par défaut Merci!!!!
    Salut Ivelios!!!

    Merci beaucoup pour ta réponse!
    Je ne connais pas encore la moitié des choses que tu utilises dans ton code haha!

    Aurais-tu une méthode simplifié pour que mon programme compile ?

    Je ne connais aucun de ces termes : List<Integer> matchFoundIntoCom2 = new LinkedList(); et souhaiterais faire un programme plus simple.

    Aurais-tu une méthode simplifiée pour que mon programme compile ?
    Genre sans tableau aussi... juste avec des boucles (for, while, if) et des manipulations de chaines.

    Ton idée de sauvegarder les variables me plaît beaucoup. Je vais essayer en faisant ça au lieu de supprimer des caractères de ma chaine quand ils sont égaux
    Le truc c'est que je ne sais pas comment faire pour ne pas que ça compte en double les caractères que le programme a déjà identifiés ayant la même valeur...

  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 : 55
    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
    Salut,

    A vrai dire, il serait plus judicieux d'utiliser un HashSet qu'une LinkedList dans ce cas. Au lieu de List<Integer> matchFoundIntoCom2 = new LinkedList(); (A noter qu'en plus cette syntaxe génère des warnings.) faire Set<Integer> matchFoundIntoCom2 = new HashSet<>(). A noter que res n'est pas utile dans ce cas : la taille de la List ou du Set est le nombre de chiffres trouvés.

    Si tu veux réaliser la même chose avec que des tableaux, tu peux utiliser un tableau de boolean : au début il contiendra que false, pour chaque index. A chaque fois que tu trouves une chiffre, au lieu d'enregistrer la positon, tu marques la position avec un boolean à true. Tester si le boolean est à true est facile pour ne pas faire le test d'égalité.

    Le code modifié
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int res = 0;
    String comb1 = "64321";
    String comb2 = "66666";
    boolean[] matchFoundIntoCom2 = new boolean[comb2.length()];
    for(int j = 0; j < comb1.length(); j++) {
        for(int i = 0; i < comb2.length(); i++) {
            if (!matchFoundIntoCom2[i] && comb1.charAt(j) == comb2.charAt(i)) {
                res++;
                matchFoundIntoCom2[i]=true; // on mémorise pour l'index i qu'on a déjà testé ce caractère
                break;// Match trouvé, on arrête d'itérer combi2 et on passe au prochain char de combi1
            }
        }
    }
    System.out.println(res);

    Par contre, il est absurde de vouloir le faire que avec des manipulations de chaines : c'est assez lourd. On peut utiliser un StringBuilder pour faire ça, ce qui est plus adapté, mais je suppose que tu ne connais pas non plus :

    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
    String comb1 = "64321";
    		String comb2 = "66666";
    		StringBuilder sb = new StringBuilder(comb2);
    		for(int j = 0; j < comb1.length(); j++) {
    		    for(int i = 0; i < comb2.length(); i++) {
    		        if ( comb1.charAt(j) == sb.charAt(i)) { 
    		            sb.setCharAt(i, 'X'); // on mémorise pour l'index i qu'on a déjà testé ce caractère
    		            break;// Match trouvé, on arrête d'itérer combi2 et on passe au prochain char de combi1
    		        }
    		    }
    		}
     
    		int res=0;
    		for(int i=0;i<sb.length(); i++) {
    			if ( sb.charAt(i)=='X' ) {
    				res++;
    			}
    		}
     
    		// ou avec une regex
    		//res = sb.toString().replaceAll("\\d", "").length();
     
    		System.out.println(res);
    Maintenant on peut simuler exactement le même traitement par manipulation de chaîne, mais c'est absurdement compliqué et lourd.

    En chaîne de caractères, revient à faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    comb2 = comb2.substring(0,i)+"X"+comb2.substring(i+1)
    j'ai mis 'X' mais on pourrait mettre n'importe quoi sauf des chiffres.

    Donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int res=0;
    		String comb1 = "64329";
    		String comb2 = "66666"; 
    		for(int j = 0; j < comb1.length(); j++) {
    		    for(int i = 0; i < comb2.length(); i++) {
    		        if ( comb1.charAt(j) == comb2.charAt(i)) { 
    		        	comb2 = comb2.substring(0,i)+"X"+comb2.substring(i+1); 
    		        	System.out.println(comb2);
    		        	res++;
    		        	break;// Match trouvé, on arrête d'itérer combi2 et on passe au prochain char de combi1
    		        }
    		    }
    		}
    		System.out.println(res);
    Si tu veux ne pas utiliser de caractère comme X, il suffit de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int res=0;
    		String comb1 = "64326";
    		String comb2 = "66666"; 
    		for(int j = 0; j < comb1.length(); j++) {
    		    for(int i = 0; i < comb2.length(); i++ ) {
    		        if ( comb1.charAt(j) == comb2.charAt(i)) { 
    		        	comb2 = comb2.substring(0,i)+comb2.substring(i+1);  
    		        	res++;
    		        	break;// Match trouvé, on arrête d'itérer combi2 et on passe au prochain char de combi1
    		        }
    		    }
    		}
    		System.out.println(res);
    Mais ces méthodes présentent le défaut non seulement de faire des manipulations de chaines (et donc une utilisation de ressources inutiles), et surtout d'altérer le paramètre de départ. Remarque qu'on pourrait le résoudre facilement en dupliquant comb2 dans une autre chaîne (mais autant le faire dans un StringBuilder).

    L'inconvénient de cette dernière méthode justement est de perdre la position des caractères : si on veut pouvoir indiquer au joueur les chiffres trouvés placés, on ne pourra pas.

  5. #5
    Futur Membre du Club
    Homme Profil pro
    comptable
    Inscrit en
    Juillet 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : comptable

    Informations forums :
    Inscription : Juillet 2015
    Messages : 8
    Points : 5
    Points
    5
    Par défaut Merci!!!!
    Salut Joel!

    T'es vraiment avancé dans java.

    En fait, c'est un exercice de niveau débutant qui me demande ça et j'ai beaucoup de contrainte.... un vrai casse tête!

    Ta dernière méthode répond presque à tout sauf que le programme ne doit pas comporter de break (par ailleurs, je n'ai pas le droit au tableau lol)
    Sais-tu comment je peux éliminer le break?

    Je connais break juste dans une boucle switch lol

  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 : 55
    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
    Sans break ?

    Réflechissons 2 secondes : à quoi sert le break ? Que fait-il ?

    Il arrête la boucle (plut tôt que prévu).

    Quels autres moyens a-t-on d'arrêter une boucle ? Le plus évident est que la condition de bouclage soit false, n'est-ce-pas ?

    Autrement écrit que i < comb2.length() soit false. Quels moyens a-t-on pour que i ne soit plus inférieur à comb2.length() ?

    Tout simplement en faisant i = comb2.length();, par exemple...

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

Discussions similaires

  1. Affectation entre chaînes de caractères
    Par saidma dans le forum Débuter avec Java
    Réponses: 4
    Dernier message: 20/10/2014, 00h24
  2. Réponses: 4
    Dernier message: 04/06/2009, 10h38
  3. Remplacer une chaîne de caractère entre deux tags seulement
    Par Olistan dans le forum Shell et commandes GNU
    Réponses: 5
    Dernier message: 08/05/2008, 14h56
  4. Réponses: 1
    Dernier message: 01/11/2006, 20h20
  5. tri par corrélation entre chaînes de caractères
    Par petitmic dans le forum Langage SQL
    Réponses: 7
    Dernier message: 09/09/2005, 16h15

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