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

Langage Java Discussion :

Comparer des entiers en tant que string


Sujet :

Langage Java

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 12
    Points : 10
    Points
    10
    Par défaut Comparer des entiers en tant que string
    salut tout le monde,

    j'essaie d'ajouter de faire une fonction pour trier les variable de type String, j'utilise donc la méthode toCompare qui renvoie une entier dont le signe dépend de la valeur unicode des chaines comparées d'après la javadoc. Jusque la tout est nickel, mais lorsque j'essaie de comparer des entiers en tant que string la fonction toCompare me renvoie du n'importe quoi.

    par exemple 4 en tant que string n'est pas supérieur à la String "2"?!! est ce normal ce résultat la?

    comment je peux comparer deux string qui peuvent contenir des caractères alphanumériques {A-Z}, {0,9}

    Merci d'avance pour votre aide, je sais que c'est simple mais c'a m'a pris une après midi entière de debuggage pour découvrir que c toCompare qui déconnait en comparant des nombres en tant que string

    merci pour votre aide

  2. #2
    Nouveau membre du Club
    Inscrit en
    Avril 2007
    Messages
    37
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 37
    Points : 29
    Points
    29
    Par défaut
    Salut,

    Je ne connais pas la fonction toCompare mais j'image qu'elle est faite grâce à une table ASCII (http://www.tableascii.com/)

    Si tu regardes bien, le nombre 4, vaut bien 4 en décimal.
    Mais le caractère 2 lui vaut 50 en décimal.
    Ce qui fait que "2" > 4 !

    Si tu veux de l'aide pour ta fonction, précise un peu ce que tu veux qu'elle fasse.
    Trier c'est bien mais selon quels critères ? Ordre Alphabétique, ordre croissant selon la somme des valeurs décimales des caractères...

    Tchao

  3. #3
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    Je ne connais pas la fonction toCompare mais j'image qu'elle est faite grâce à une table ASCII (http://www.tableascii.com/)
    Non: c'est fait grâce à la velur en Unicode, pas ASCII.
    Ceci dit, pour les caractères du Latin basique (dont font partie les chiffres qu'on connait), les codes ascii et unicode correpondent grosso modo.

    Citation Envoyé par Matt112 Voir le message
    Si tu regardes bien, le nombre 4, vaut bien 4 en décimal.
    Mais le caractère 2 lui vaut 50 en décimal.
    Ce qui fait que "2" > 4 !
    Non: en ascii, le caractère 2 est bien codé 50, mais le caractère 4 est codé 52.
    L'ordre est donc bien respecté !

  4. #4
    Nouveau membre du Club
    Inscrit en
    Avril 2007
    Messages
    37
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 37
    Points : 29
    Points
    29
    Par défaut
    Ah oui exact, au temps pour moi... d'autant plus que je donne le lien du tableau où c'est marqué :p
    Merci

  5. #5
    Inactif  
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    885
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 885
    Points : 1 320
    Points
    1 320
    Par défaut
    Salut,

    String.compareTo fonctionne pourtant bien (comme c'est spécifié dans la javadoc, comparaison selon tri par ordre lexicographique, et 3 résultats possibles), non ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    "4".compareTo("3");
    // ou bien
    "tralala 4".compareTo("tralala 3")
    donne bien 1.

    L'opération dans le sens inverse renvoyant bien -1.

    Pourrais-tu détailler ton code ?

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 12
    Points : 10
    Points
    10
    Par défaut
    le problème en faite ne vient pas de mon code, je fait vraiment des testes bêtes koi: essayer

    "33".toCompare("4") ca donne -1 non?!

    apparemment les machines trient les string d'une façon qui donne des résultats qui diffèrent parfois de ce qu'on attend nous les humains. Fin j'ai trouvé sur le net des articles qui parlent du trie naturel "Natural order string comparaison" qui utlise le Collator Java.

    ce lien : http://www.javapractices.com/topic/T...tion.do?Id=207 traite bien ce sujet. Sauf que j'aimerai bien que si qlqn pourrait nous expliquer d'avantage les collator pour mieux cerner le trie des string en java.

  7. #7
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    Citation Envoyé par power of mind Voir le message
    le problème en faite ne vient pas de mon code, je fait vraiment des testes bêtes koi: essayer

    "33".toCompare("4") ca donne -1 non?!
    Oui, ça donne -1 (ie. 33 est avant 4) et c'est parfaitement normal.

    Il parle du problème de localisation, pas directement des comparaisons de chaînes contenant des nombres. En plus, tu as visiblement loupé la phrase la plus importante:
    The reason is that programmers tend to apply them to tasks they really aren't meant for
    En effet, le problème vient de toi : tu n'a pas bien cerné la finalité de la fonction compareTo().

    Et ... entre nous : quand on tombe sur des résultats qui ne sont pas ceux espérés et que lesdits résultats proviennent d'une fonction standard d'un framework utilisé par des millions de développeurs tous les jours, il y a infiniment plus de chances que le problème vienne de soi, plutôt que d'être tombé sur un bug que jamais personne n'a détecté avant.


    Pour revenir au sujet: la fonction compareTo() s'applique à des chaînes de caractères.
    Elle ne compare pas la valeur numérique de ce qu'elle contient, mais elle compare la valeur de chaque caractère un par un, de la même façon que tu compares une à une les lettres de deux mots pour le mettre dans l'ordre alphabétique.

    Ici, au premier caractère tu as '3' pour la première chaîne et '4' pour la deuxième. 3 étant un caractère avec un code inférieur au code du caractère '4', la fonction te renvoie que la chaîne '33' est inférieure à la chaîne '4'.

    Toi, ce que tu veux comparer, c'est des nombres entiers.
    Dans ce cas, commence par convertir tes chaines de caractères en entiers avant de comparer les entiers eux même:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    String strA = "33";
    String strB = "4";
     
    int a = Integer.parseInt(strA);
    int b = Integer.parseInt(strB);
     
    System.out.println("a<b = " + (a<b)  );

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 12
    Points : 10
    Points
    10
    Par défaut
    Merci Nouknouk pour ta réponse,

    En fait moi je veux pas comparer des entiers ce que je veux faire c'est comparer des string comportant des caractères alphanumériques des lettres, et des nombres, mes chaines peuvent être purement des nombres(entiers ou doubles) comme ils peuvent des string pures ou encore des chaines mixtes. comment faire ce genre de trie sans avoir recour au conversion car je sais pas le type de mes chaines avant de lancer ma fonction de trie?

  9. #9
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    Ben dans ton cas tu as un format d'entrée complexe (qui a dit merdique ? ).

    Donc à toi de te débrouiller pour cerner complètement ce que tu veux faire: tu es le seul à connaître les types de chaînes que tu as en entrée et les résultats que tu veux obtenir pour chaque cas de figure.

    En attendant, une chose est sûre: il n'y a pas de fonction java toute faite qui te permettra en un seul coup de comparer des chaînes mixtes en comparant les parties 'mots' par ordre alphabétique et les parties 'nombres' dans l'ordre croissant.

    Il ne te reste plus qu'à développer ta propre fonction avec tes petites mains

  10. #10
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    1
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 1
    Points : 1
    Points
    1
    Par défaut up
    Bonjour,
    Un petit up.
    Je suis confronté au même problème, pour afficher une liste de fichiers dans le même ordre que l'explorateur Windows:

    fichier1
    fichier2
    ...
    fichier10

    et non

    fichier1
    fichier10
    fichier2
    ...

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    81
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 81
    Points : 84
    Points
    84
    Par défaut
    Windows te les affichera dans cet ordre si le tri est par nom de fichier :

    fichier1
    fichier10
    fichier2

    Arnaud

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    81
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 81
    Points : 84
    Points
    84
    Par défaut
    Désolé il semble que je me sois trompé sur l'ordre Windows

    Arnaud

  13. #13
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Comme cela a été dit la comparaison par défaut (via String.compareTo() donc) se contente de comparer les codes Unicode des caractères, et peuvent donc fournir des résultat un peu "bizarre" ('Z' est devant 'a' par exemple)

    Les Collators permettent de prendre en compte diverses spécificités locales, et non plus la valeur unicode du caractère. Grosso-modo cela permet d'obtenir un vrai tri alphabétique
    Ils peuvent également carrément ignorer certaines différences pour des comparaisons plus souple (voir la FAQ : Comment comparer des chaînes de caractères selon la Locale ?).



    Maintenant sauf erreur il n'existe rien en standard qui permette la comparaison sur la valeur des chiffres contenu dans une chaine...

    Mais ce n'est pas bien méchant à implémenter : En cas de différence entre deux chaines, il faut comparer alternativement les valeurs texte et numérique qui se suivent, jusqu'à trouver la différence entre les deux...


    Au final cela se traduit par un comparator du style :
    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
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    /**
     * Comparaison de chaine de caractère qui prend en compte la valeur des sections numériques...
     * 
     * @author adiGuba
     */
    class NaturalStringComparator implements Comparator<String> {
     
    	/** Le comparateur qui sera utilisé pour comparer les chaines */
    	private final Comparator<? super String> stringCompare;
     
    	/**
             * Comparaison des chaines par défaut (avec compareTo()).
             */
    	public NaturalStringComparator() {
    		this(null);
    	}
     
    	/**
             * Comparaison des chaines selon un comparateur spécifique.
             */
    	public NaturalStringComparator(Comparator<? super String> comparator) {
    		this.stringCompare = comparator;
    	}
     
    	/**
             * Retourne l'index du prochain caractère d'un certain type.
             * @param str La chaine à lire
             * @param start Index de départ de la recherche
             * @param noDigit : true pour rechercher n'importe quel caractètre qui ne soit pas un chiffre
             */
    	private int indexOf(String str, int start, boolean noDigit) {
    		if (start>=0) {
    			final int LEN = str.length();
    			for (int i=start; i<LEN; i++) {
    				if (Character.isDigit(str.charAt(i))^noDigit) {
    					return i;
    				}
    			}
    		}
    		return -1;
    	}
     
    	/**
             * Retourne la valeur entière entre deux emplacements de la chaine
             * @param str La chaine à lire
             * @param start Début de la valeur entière
             * @param end Fin de la valeur entière
             * @return La valeur entière correspondante
             */
    	private int valueOf(String str, int start, int end) {
    		if (end>=0) {
    			return Integer.valueOf(str.substring(start, end));
    		}
    		return Integer.valueOf(str.substring(start));
    	}
     
    	/**
             * Effectue une comparaison de chaine selon le comparateur fourni
             */
    	private int stringCompare(String o1, String o2) {
    		if (this.stringCompare!=null) {
    			return this.stringCompare.compare(o1, o2);
    		}
    		return o1.compareTo(o2);
    	}
     
    	/**
             * Comparaison des chaines en prenant en compte la valeur des nombres.
             */
    	@Override
    	public int compare(String o1, String o2) {
    		final int defaultResult = stringCompare(o1, o2);
    		if (defaultResult!=0) {
    			// Si les chaines sont différentes :
     
    			int start1 = 0;
    			int start2 = 0;
    			int end1 = 0;
    			int end2 = 0;
     
    			// On récupère les index des prochains chiffres 
    			int idx1 = indexOf(o1, start1, false);
    			int idx2 = indexOf(o2, start2, false);
     
    			// Tant qu'on a bien un chiffre de chaque coté :
    			while (idx1>=0 && idx2>=0) {
     
    				// On compare les chaines avant les chiffres :
    				int result = stringCompare(o1.substring(start1,idx1), o2.substring(start2,idx2));
    				if (result!=0) {
    					// Si on trouve une différence, on peut déjà s'arrêter :
    					return result;
    				}
     
    				// On récupère l'index du caractères suivant :
    				end1 = indexOf(o1, idx1, true);
    				end2 = indexOf(o2, idx2, true);
     
    				// On récupère la valeur entière du chiffre trouvé :
    				int value1 = valueOf(o1, idx1, end1);
    				int value2 = valueOf(o2, idx2, end2);
     
    				// Si on trouve une différence on la prend en compte :
    				if (value1<value2) {
    					return -1; // value1 plus petit que value2
    				} else if (value1>value2) {
    					return 1; // value1 plus grand que value2
    				}
     
    				// En on continue sur les mêmes index :
    				start1 = end1;
    				start2 = end2;
     
    				// On récupère les index des nombres
    				idx1 = indexOf(o1, start1, false);
    				idx2 = indexOf(o2, start2, false);
    			}
    		}
     
    		// On n'a trouvé aucune différence dans les chiffres :
    		return defaultResult;
    	}
     
    }

    a++

Discussions similaires

  1. Variable interpretée en tant que string
    Par Woocher dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 20/03/2009, 09h09
  2. [Débutante]Balise HTML en tant que String
    Par bbyoulie dans le forum Débuter avec Java
    Réponses: 4
    Dernier message: 09/12/2008, 13h30
  3. [MySQL] comparer des entiers
    Par angeleweb dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 20/12/2007, 18h21
  4. Réponses: 1
    Dernier message: 14/10/2007, 20h15
  5. [débutant]obtenir un unsigned char en tant que String
    Par NorthernLights dans le forum C++
    Réponses: 2
    Dernier message: 03/02/2006, 10h30

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