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

C# Discussion :

[filtre & string] Déduire d'après 2 chaines de caractères une liste de filtre


Sujet :

C#

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    70
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 70
    Points : 51
    Points
    51
    Par défaut [filtre & string] Déduire d'après 2 chaines de caractères une liste de filtre
    Bonjour,

    Je vais vous résumer ma situation : j'utilise une méthode qui prend en entrée une chaine de caractères qui lui sert de filtre, par exemple "ab*". Elle ne prend qu'UN seul filtre en entrée et je n'ai pas le choix.
    Mes utilisateurs m'ont demandé de pouvoir, via l'IHM, saisir 2 bornes par exemple "ax*" et "cbe*".

    Je cherche donc un moyen simple d'isoler tous les filtres possibles compris entre ces 2 chaines.

    Par exemple si on m'indique "ax* et "cbe*", j'aimerai être capable de me construire la liste suivante:
    ax*
    ay*
    az*
    b*
    ca*
    cba*
    cbb*
    cbc*
    cbd*
    cbe*


    de sorte à pouvoir appeler la fameuse méthode ne prenant qu'un filtre en entrée.

    Le seul moyen que je vois à l'heure actuelle est du découpage de chaine barbare et de l'analyse caractère par caractère. Or je ne trouve pas ça élégant, je souhaitais donc savoir si quelqu'un avait une solution plus propre!

    Merci à vous!

    Rastamath69

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    70
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 70
    Points : 51
    Points
    51
    Par défaut
    Bonjour à tous,

    Je vois que ce problème n'inspire pas grand monde...

    Je vous propose donc ma solution. A base de récursion et de parcours de caractères, elle n'est pas forcément élégante, mais elle a le mérite de marcher (tout du moins je ne trouve plus de bugs à travers mes jeux de 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
    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
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
            /// <summary>
            /// Méthode qui construit une liste de filtre 
            /// </summary>
            private List<String> PreparationListeFiltre(String borneInferieur, String borneSuperieur)
            {
                String tampon = String.Empty;
                List<String> listeRetour = new List<String>();
     
                try
                {
                    borneInferieur = borneInferieur.ToUpper();
                    borneSuperieur = borneSuperieur.ToUpper();
     
                    //On met en place les * s'il n'y en a pas
                    if (!borneInferieur.EndsWith("*"))
                        borneInferieur += "*";
     
                    if ((borneSuperieur.CompareTo(String.Empty) == 0) || (borneSuperieur.CompareTo("*") == 0))
                        borneSuperieur = "Z";
     
                    if (!borneSuperieur.EndsWith("*"))
                        borneSuperieur += "*";
     
                    //Vérification de la cohérence des filtres
                    if (!VerifChaine1PlusPetiteQueChaine2(borneInferieur, borneSuperieur))
                        throw new Exception("Premier filtre alphabétiquement moins grand que le deuxième.");
     
                    tampon = borneInferieur;
                    listeRetour.Add(tampon);
                    while (tampon != borneSuperieur)
                    {
                        tampon = Chaine_Suivante(tampon, borneSuperieur, false);
                        listeRetour.Add(tampon);
                    }
                }
                catch (Exception ex)
                {
                    Trace.TraceError("Erreur lors de la préparation de la liste des filtre pour isoler les différents utilisateurs.", ex.Message);
                    throw ex;
                }
     
                return listeRetour;
            }
     
            /// <summary>
            /// Retourne un booléen pour indiquer que chaine1 est bien placée avant chaine2 dans l'alphabet
            /// </summary>
            /// <param name="chaine1"></param>
            /// <param name="chaine2"></param>
            /// <returns></returns>
            private bool VerifChaine1PlusPetiteQueChaine2(String chaine1, String chaine2)
            {
                if (chaine1 == chaine2)
                    return true;
     
                if (chaine1.Substring(0, 1) == chaine2.Substring(0, 1))
                    return VerifChaine1PlusPetiteQueChaine2(chaine1.Substring(1, chaine1.Length - 1), chaine2.Substring(1, chaine2.Length - 1));
                else if (CharToInt(chaine1.Substring(0, 1)) > CharToInt(chaine2.Substring(0, 1)))
                    return false;
                else
                    return true;
            }
     
            /// <summary>
            /// Retourne une chaine qui correspond au filtre suivant attendu
            /// Cette méthode ne traite que des filtres ayant des majuscules. Les caractères autres que les 25 de l'alphabet ou que l'"*"
            /// ne sont pas tolérés.
            /// </summary>
            /// <param name="filtre1">Plus petit paramètre attendu  = "A*"</param>
            /// <param name="dernierFiltre">Filtre auquel il faudra s'arrêter</param>
            /// <param name="plusGrandDejaTrouve">Booléen indiquant si on a déjà trouvé une preuve de la supéritorité
            /// alphabétique de dernierFiltre sur filtre1</param>
            /// <returns>Renvoie la chaine représentant le filtre suivant de filtre1 par rapport à dernierFiltre</returns>
            private string Chaine_Suivante(String filtre1, String dernierFiltre, bool plusGrandDejaTrouve)
            {
                if (filtre1 != String.Empty && dernierFiltre != String.Empty)
                {
                    byte premiereLettreDernierFiltre = (byte)dernierFiltre.ToCharArray(0, 1)[0];
                    byte premiereLettrePremierFiltre = (byte)filtre1.ToCharArray(0, 1)[0];
     
                    //on élimine les premières lettres si elles sont égales et qu'on est toujours à égalité entre les 2 chaines
                    if (Convert.ToInt32(premiereLettreDernierFiltre) == Convert.ToInt32(premiereLettrePremierFiltre) && !plusGrandDejaTrouve)
                    {
                        return (filtre1.Substring(0, 1) + Chaine_Suivante(filtre1.Substring(1, filtre1.Length - 1), dernierFiltre.Substring(1, dernierFiltre.Length - 1), plusGrandDejaTrouve));
                    }
                    // si le caractère suivant du premier caractère du premier filtre, est égal au premier caractère du dernier
                    //filtre et que ce nous ne sommes pas à la fin du dernier filtre
                    else if (Convert.ToInt32(premiereLettreDernierFiltre) == (Convert.ToInt32(premiereLettrePremierFiltre) + 1) && !plusGrandDejaTrouve && !DerniereLettre(dernierFiltre))
                    {
                        return (LettreSuivante(filtre1.Substring(0, 1)) + Chaine_Suivante(filtre1.Substring(1, filtre1.Length - 1), dernierFiltre.Substring(1, dernierFiltre.Length - 1), true));
                    }
                    else if (filtre1.Substring(0, 1) == "*") //cas spécifique où on doit réagrandir la chaine filtre1
                    {
                        if (dernierFiltre.Substring(0, 1) == "A" && !DerniereLettre(dernierFiltre))
                        {
                            return "A" + Chaine_Suivante(filtre1, dernierFiltre.Substring(1, dernierFiltre.Length - 1), plusGrandDejaTrouve);
                        }
                        else
                        {
                            return "A*";
                        }
                    }
                    else
                    {
                        //Si on arrive aux dernières lettres
                        if (DerniereLettreAvantZ(filtre1))
                            return LettreSuivante(filtre1.Substring(0, 1)) + "*";
     
                        if (dernierFiltre == "*")
                            return (filtre1.Substring(0, 1) + Chaine_Suivante(filtre1.Substring(1, filtre1.Length - 1), dernierFiltre, plusGrandDejaTrouve));
     
                        //si le premier caractère de Filtre1 est plus petit que celui de dernierFiltre 
                        if ((CharToInt(filtre1.Substring(0, 1)) <= CharToInt(dernierFiltre.Substring(0, 1))) || plusGrandDejaTrouve)
                        {
                            return (filtre1.Substring(0, 1) + Chaine_Suivante(filtre1.Substring(1, filtre1.Length - 1), dernierFiltre.Substring(1, dernierFiltre.Length - 1), true));
                        }
                        else
                        {
                            //ERREUR : qui ne peut pas arriver si les chaines ont été vérifiées avant 
                        }
                    }
                }
                return String.Empty;
            }
     
            /// <summary>
            /// Indique pour une chaine qui se termine par *, et potentiellement des "Z" avant l'"*", s'il ne reste qu'une 
            /// lettre avant.
            /// Exemple: pour EZZ* => VRAI
            ///          pour DZMZ* => FAUX
            /// </summary>
            /// <param name="filtre1"></param>
            /// <returns></returns>
            private bool DerniereLettreAvantZ(String filtre1)
            {
                if (filtre1.Substring(1, 1) == "*")
                    return true;
                else if (filtre1.Substring(1, 1) != "Z")
                    return false;
                else
                    return DerniereLettreAvantZ(filtre1.Substring(1, filtre1.Length - 1));
            }
     
            /// <summary>
            /// Méthode prenant un Code Ascii en paramètre et retourne le caractère correspondant
            /// </summary>
            /// <param name="codeAscii"></param>
            /// <returns></returns>
            private String IntToChar(Int32 codeAscii)
            {
                String resultat = String.Empty;
                byte b = (byte)codeAscii;
                resultat = ((char)b).ToString();
                return resultat;
            }
     
            /// <summary>
            /// Méthode prenant un caractère en entrée et qui retourne son code ascii
            /// </summary>
            /// <param name="car"></param>
            /// <returns></returns>
            private Int32 CharToInt(String car)
            {
                Int32 resultat = 0;
                if (car != String.Empty)
                {
                    char cara = car.ToCharArray()[0];
                    resultat = (Int32)cara;
                }
                return resultat;
            }
     
            /// <summary>
            /// Retourne le caractère qui suit dans la table ASCII
            /// </summary>
            /// <param name="caractere"></param>
            /// <returns></returns>
            private String LettreSuivante(String caractere)
            {
                String retour = String.Empty;
                if (caractere.Length == 1)
                {
                    Int32 code = CharToInt(caractere);
                    code++;
                    retour = IntToChar(code);
                }
                else
                {
                    retour = caractere;
                }
     
                return retour;
            }
     
            /// <summary>
            /// Définit, pour une chaine qui se termine par une *, si nous sommes à la dernière lettre
            /// </summary>
            /// <param name="chaine"></param>
            /// <returns></returns>
            private bool DerniereLettre(String chaine)
            {
                return (chaine.Substring(1, 1) == "*");
            }
    La méthode principale est "PreparationListeFiltre" qui prend en paramètre les deux bornes entre lesquelles on souhaite la liste des filtres. Et elle vous retourne une liste de string (= la liste des filtres).

    En espérant que cela puisse servir à quelqu'un!

    Bonne journée!

    Rastamath69

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 02/11/2008, 20h38
  2. Réponses: 4
    Dernier message: 15/05/2008, 11h47
  3. Réponses: 0
    Dernier message: 03/03/2008, 12h02
  4. [MEX] Passer une chaine de caractères à une fonction mex
    Par onaipadesmickey dans le forum MATLAB
    Réponses: 1
    Dernier message: 27/02/2008, 09h39
  5. [Listes ou Chaines de caractères] Une idée..
    Par KiLVaiDeN dans le forum Algorithmes et structures de données
    Réponses: 3
    Dernier message: 25/04/2006, 11h54

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