Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1055 connectés 

  FORUM HardWare.fr
  Programmation
  Algo

  Un algo pas si simple...

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Un algo pas si simple...

n°292391
El_gringo
Posté le 23-01-2003 à 10:37:26  profilanswer
 

Le contexte est le suivant :
J'ai une appli qui rempli une table de log.
On veut permettre à l'utilisateur de consulter cette table depuis l'interface de mon appli.
Mais cette table est généralement énorme, donc afficher tous les les enregistrements prendrait un temps énorme.
un des champ de ma table de log est MSGID. ce champ identifie le type de message d'un enregistrment.
J'ai donc opté pour la solution suivante :
offrir la possibilité de définir un filtre sur ce MSGID, sachant que :
| veut dire que la valeur suivante est également visualisable.
- représente un interval de valeurs visualisables.
par exemple le filtre "5000-5999|6001" autorise la visualisation des messages dont le MSGID est compris entre 5000 et 5999, plus ceux dont le MSGID est 6001.
Je pensait que l'algo serait assez simple, mais je suis en train de rajouter tout un tas de cas particuliers, je m'en sort pas.  
Pour l'instant, mon algo en est là (c'est codé en C) :
Je commence par séparer les 2 types d'éléments : opérateurs '-' et '|', et chiffres. Je stocke tous les opérateurs dans un tableau, et tous les chiffres dans un autre.
ensuite, mon algo en est là :

Code :
  1. char szPartToAdd[32];                // Partie de clause where à ajouter
  2.                     char curentOp    = '\0';             // Opérateur courant
  3.                     char nextOp      = '\0';             // Opérateur précédant
  4.                     long lPrevMSGID  = '\0';             // MSGID précédant l'opérateur courant
  5.                     long lNextMSGID  = '\0';             // MSGID suivant l'opérateur courant
  6.                     BOOL bFirstCondition = TRUE;
  7.                     BOOL bColNameWrited  = FALSE;
  8.                     if (lNbOp == 0)
  9.                     {
  10.                         memset (szPartToAdd, 0, sizeof (szPartToAdd));
  11.                         sprintf (szPartToAdd, "MSGID = %ld", lplAllMSGID[0]);
  12.                         strcat (szWhereClause, szPartToAdd);
  13.                     }
  14.                     else
  15.                     {
  16.                         for (lCpt = 0; lCpt <= lNbOp; lCpt++)
  17.                         {
  18.                             memset (szPartToAdd, 0, sizeof (szPartToAdd));
  19.                             if (!bColNameWrited)
  20.                             {
  21.                                 if (bFirstCondition)
  22.                                 {
  23.                                     strcat (szWhereClause, "MSGID " );
  24.                                     bFirstCondition = FALSE;
  25.                                 }
  26.                                 else
  27.                                    strcat (szWhereClause, "OR MSGID " );
  28.                                 bColNameWrited = TRUE;
  29.                             }
  30.                             curentOp   = szAllOp[lCpt];
  31.                             nextOp     = szAllOp[lCpt+1];
  32.                             lPrevMSGID = lplAllMSGID[lCpt];
  33.                             lNextMSGID = lplAllMSGID[lCpt+1];
  34.                             if (curentOp == '-')
  35.                             {
  36.                                 sprintf (szPartToAdd, "BETWEEN %ld AND %ld ", lPrevMSGID, lNextMSGID);
  37.                                 bColNameWrited = FALSE;
  38.                             }
  39.                             else if (curentOp == '|')
  40.                             {
  41.                                 if (lCpt == 0)
  42.                                 {
  43.                                     sprintf (szPartToAdd, "= %ld ", lPrevMSGID);
  44.                                     bColNameWrited = FALSE;
  45.                                 }
  46.                                 else if ((lCpt == lNbOp) || (nextOp == '|'))
  47.                                 {
  48.                                     sprintf (szPartToAdd, "= %ld ", lNextMSGID);
  49.                                     bColNameWrited = FALSE;
  50.                                 }
  51.                                 else
  52.                                 {
  53.                                     continue;
  54.                                 }
  55.                             }
  56.                             strcat (szWhereClause, szPartToAdd);
  57.                         }
  58.                     }


 
Bref, un 'ti coup de main serait le bienvenu !

mood
Publicité
Posté le 23-01-2003 à 10:37:26  profilanswer
 

n°292453
BifaceMcLe​OD
The HighGlandeur
Posté le 23-01-2003 à 11:40:50  profilanswer
 

Réécris ton code pour en faire un automate. En voici le pseudo-code :
 
variables
  Liste : tableau de couples d'entiers   -- pour désigner des intervalles de valeurs
  nombre : entier    -- pour construire un entier caractère par caractère
  intervalle : booléen
 
intervalle = FAUX
nombre        = 0
 
Pour chaque caractère car
    selon car
        '0'-'9':
            nombre = nombre * 10 + chiffre-correspondant
 
        '-':
            nombre     = 0
            intervalle = VRAI
            ajouter le couple (nombre, 0) à liste
 
        '|':
            si intervalle
                alors modifier le 2ème terme du dernier couple de liste avec nombre
                sinon ajouter le couple (nombre, nombre) à liste
            nombre     = 0
            intervalle = FAUX
    fin de sélection
fin de boucle
 
Voilà l'idée générale. Après, tu brodes.

n°292460
El_gringo
Posté le 23-01-2003 à 11:51:05  profilanswer
 

L'idée me plait assez.
Ms là je suis en train de partir sur autre chose.
Au lieu d'isoler tous les opérateurs, je constitue un tableau isolant tous les "OR" sql (caractère '|' dans mon codage).
Ainsi, si on a ça "5001|5002-6001|7002|6005-6007", je stocke 5001, 5002-6001, 7002, 6005-6007. Ensuite, pour chaque élément de ce nouveau tableau, je fait soit une égalité, soit un interval, en ajoutant des OR pour chacun.
ça me parait + simple comme ça...

n°292480
BifaceMcLe​OD
The HighGlandeur
Posté le 23-01-2003 à 12:25:33  profilanswer
 

Effectivement, cela peut sembler plus simple à première vue de se baser sur un tokenizer.
 
Mais à mon avis, le code final sera plus complexe, plus long en nombre de ligne de code source, tout en étant moins évolutif, et qui plus est plus lent et plus gourmand en mémoire (oui, oui, tout ça ! :D ) qu'un bête automate à états finis.
 
Mais tu es libre de découvrir cela par toi-même ! ;)

n°298652
Musaran
Cerveaulté
Posté le 01-02-2003 à 05:50:00  profilanswer
 

Reconnaître, stocker et analyser des sous-séquences intermédiaires... C++ n'est pas fait pour ça, il ne facilite pas les choses.
 
J'ai déjà plusieurs fois fait une analyse de ce genre, et j'ai toujours fini par aboutir à l'exemple de BifaceMcLeOD.
 
Je m'étais dit "tiens, ça ressemble à la description d'un automate" :) .


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
n°298668
BifaceMcLe​OD
The HighGlandeur
Posté le 01-02-2003 à 09:10:54  profilanswer
 

:ange:  :jap:


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Algo

  Un algo pas si simple...

 

Sujets relatifs
Par le plus simple des hasards... (affichage presque aleatoire)comment changer la couleur d'un texte de maniere simple
[PHP] Gerer les news --> SQL ou fichier simpleUrgent aide hyper simple en javascript pour mon interro.
[Algo/C] Grande chaine de caractères pour test d'un algorithmeSQL Question simple...
MasterMind => pb d'algo..MasterMind => pb d'algo..
Quel éditeur simple et complet pour dev en ASP ?recherche algo balistique (bonus : jeux inside ! )
Plus de sujets relatifs à : Un algo pas si simple...


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR