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

Algorithmes et structures de données Discussion :

rechercher une sous-chaine dans un set de 40 000 noms


Sujet :

Algorithmes et structures de données

  1. #21
    Membre du Club Avatar de floopi51
    Inscrit en
    Octobre 2008
    Messages
    136
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 136
    Points : 62
    Points
    62
    Par défaut
    Citation Envoyé par Trap D Voir le message
    Salut

    Mes données étaient rangées dans un gros fichier codé, (ça n'a aucune importance pour le traitement).
    Je faisais un tri alphabétique à partir de la première lettre, j'obtenais un premier index, puis un tri alphabétique à partir de la deuxième lettre etc. Les index renvoyaient à l'offset du mot dans le fichier. Pour accélérer encore la recherche, pour chaque index, je sauvegardais un tableau où étaient indiqués les offset dans l'index du premier mot débutant par a, par b pac c...
    Je trouvais ensuite les mots par une simple recherche dichotomique avec dejà 2 bornes correctes.
    Ok, merci. Comment as-tu procédé pour enregistrer tes index dans un fichier ?

  2. #22
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    J'ai enregistré les 2 niveaux de fichiers binaires, en fait 2 X 25 fichiers car la longueur maximale des mots utilisés était 25.
    Les tableaux d'index (le deuxième niveau d'index) sont chargés en mémoire, les premiers fichiers du premier niveau d'index sont gros, puis au fur et à mesure qu'on avance ils deviennent de plus en plus petits (moins de mots de 15 lettres, 16 lettres etc).
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  3. #23
    Membre du Club Avatar de floopi51
    Inscrit en
    Octobre 2008
    Messages
    136
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 136
    Points : 62
    Points
    62
    Par défaut
    Citation Envoyé par Trap D Voir le message
    J'ai enregistré les 2 niveaux de fichiers binaires, en fait 2 X 25 fichiers car la longueur maximale des mots utilisés était 25.
    Les tableaux d'index (le deuxième niveau d'index) sont chargés en mémoire, les premiers fichiers du premier niveau d'index sont gros, puis au fur et à mesure qu'on avance ils deviennent de plus en plus petits (moins de mots de 15 lettres, 16 lettres etc).
    OK merci pour tes explications. je vois un peu mieux comment fonctionne l'indexation maintenant.
    Bon ben y'a plus K Je vais regarder comment je pourrais travailler avec un index.
    Entre temps, j'ai aussi trouvé un exemple de DAWG ici qui, d'après "la littérature" est très performant pour la recherche de texte.
    Donc 2 bonnes pistes à explorer.

  4. #24
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Bon courage pour la suite.
    Pense à utiliser les facilités offertes par certaines fonctions qui permettent de comparer alphabétiquement les lettres accentuées.
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  5. #25
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    C'est sans doute un peu bourrin, mais j'ai simplement construit une hashtable de tous les sous-chaines de tous les mots, qui enregistre pour chaque sous-chaine la liste des mots auquel elle appartient.

    En Python:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from collections import defaultdict
    substringDict = defaultdict(list)
     
    def add_word(ssd, word):
        for i in range(len(word)):
            for j in range(i, len(word)):
                ssd[word[i:j+1]].append(word)
     
    for word in wordlist:   # wordlist contient la liste de mots
        add_word(substringDict, word)
    Avec une liste de 22740 mots de longueur moyenne de 8 caractères, j'ai:
    • nombre de sous-chaines uniques = 173047
    • nombre moyen de mots par sous-chaine = 39.5
    • utilisation mémoire = 24 MO, soit un peu plus d'1 KO par mot
    • temps pour construire le dictionnaire: environ 1 seconde

    Retrouver la liste des mots pour une sous-chaîne est très rapide (c'est juste un lookup dans une hashtable), et l'algo est très facile, mais cela prend pas mal de mémoire.

    La construction du dictionnaire (hashtable) est (en nombre d'étapes) O(n*m^2) où n est le nombre de mots et m est la longueur moyenne des mots. Si la longueur moyenne des chaînes à indexer est longue, cette approche risque de ne plus être praticable...

  6. #26
    Membre du Club Avatar de floopi51
    Inscrit en
    Octobre 2008
    Messages
    136
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 136
    Points : 62
    Points
    62
    Par défaut
    Citation Envoyé par dividee Voir le message
    C'est sans doute un peu bourrin, mais j'ai simplement construit une hashtable de tous les sous-chaines de tous les mots, qui enregistre pour chaque sous-chaine la liste des mots auquel elle appartient.

    En Python:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from collections import defaultdict
    substringDict = defaultdict(list)
     
    def add_word(ssd, word):
        for i in range(len(word)):
            for j in range(i, len(word)):
                ssd[word[i:j+1]].append(word)
     
    for word in wordlist:   # wordlist contient la liste de mots
        add_word(substringDict, word)
    Avec une liste de 22740 mots de longueur moyenne de 8 caractères, j'ai:
    • nombre de sous-chaines uniques = 173047
    • nombre moyen de mots par sous-chaine = 39.5
    • utilisation mémoire = 24 MO, soit un peu plus d'1 KO par mot
    • temps pour construire le dictionnaire: environ 1 seconde

    Retrouver la liste des mots pour une sous-chaîne est très rapide (c'est juste un lookup dans une hashtable), et l'algo est très facile, mais cela prend pas mal de mémoire.

    La construction du dictionnaire (hashtable) est (en nombre d'étapes) O(n*m^2) où n est le nombre de mots et m est la longueur moyenne des mots. Si la longueur moyenne des chaînes à indexer est longue, cette approche risque de ne plus être praticable...
    Wouahou Merci !
    Par contre je ne connais pas le Python. (je travaille en C, Objective C, vaguement java) du coup je ne comprend pas en détail les différentes étapes du code. Tu pourrais me l'écrire en algo simple ?
    Quand tu dis que tu as enregistré toutes les sous-chaînes, le "motif" de base d'une sous-chaine c'est quoi ? une syllabe ?

  7. #27
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par floopi51 Voir le message
    Wouahou Merci !
    Par contre je ne connais pas le Python. (je travaille en C, Objective C, vaguement java) du coup je ne comprend pas en détail les différentes étapes du code. Tu pourrais me l'écrire en algo simple ?
    Quand tu dis que tu as enregistré toutes les sous-chaînes, le "motif" de base d'une sous-chaine c'est quoi ? une syllabe ?
    L'idée c'est de construire pour chaque sous-chaine possible la liste des mots dans laquelle la sous-chaine apparait.

    [sous_chaine1] = {mot1, mot2, mot3, ...}
    [sous_chaine2] = {mot4, mot5, mot6, ...}


    Pour cela, on énumère toutes les sous-chaines présente dans chaque mot, et on met à jour les listes.

    tortue

    [t] = {tortue}
    [o] = {tortue}
    [r] = {tortue}
    [t] // déja traité
    [u] = {tortue}
    [e] = {tortue}

    [to] = {tortue}
    [or] = {tortue}
    [rt] = {tortue}
    [tu] = {tortue}
    [ue] = {tortue}

    [tor] = {tortue}
    [ort] = {tortue}
    [rtu] = {tortue}
    [tue] = {tortue}

    ...

    turquoise

    [t] = {tortue, turquoise}
    [u] = {tortue, turquoise}
    [r] = {tortue, turquoise}
    [q] = {turquoise}
    [u] // déja traité
    [o] = {tortue, turquoise}
    ...

    [tu] = {tortue, turquoise}
    [ur] = {turquoise}
    ...
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  8. #28
    Membre du Club Avatar de floopi51
    Inscrit en
    Octobre 2008
    Messages
    136
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 136
    Points : 62
    Points
    62
    Par défaut
    Citation Envoyé par pseudocode Voir le message
    L'idée c'est de construire pour chaque sous-chaine possible la liste des mots dans laquelle la sous-chaine apparait.

    [sous_chaine1] = {mot1, mot2, mot3, ...}
    [sous_chaine2] = {mot4, mot5, mot6, ...}


    Pour cela, on énumère toutes les sous-chaines présente dans chaque mot, et on met à jour les listes.

    ...
    OK merci ! Je comprend mieux maintenant.
    Par contre si je fais ça, mon index (c'est à dire ma liste de sous-chaines) va être énorme.
    Il va falloir que je retraite mon index pour l'alléger.

  9. #29
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Citation Envoyé par floopi51 Voir le message
    Par contre si je fais ça, mon index (c'est à dire ma liste de sous-chaines) va être énorme.
    Il va falloir que je retraite mon index pour l'alléger.
    Oui c'est assez gros, mais comme c'est stocké dans une table de hachage, l'accès est rapide. Les tables de hachage sont présentes dans la librairie standard de beaucoup de langages: HashMap en Java, hash_map dans la STL (C++). Je ne connais pas Objective C, mais apparemment ça existe aussi (NSDictionary). Sauf en C, qui ne possède pas grand chose comme conteneur standard

  10. #30
    Membre du Club Avatar de floopi51
    Inscrit en
    Octobre 2008
    Messages
    136
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 136
    Points : 62
    Points
    62
    Par défaut
    Citation Envoyé par dividee Voir le message
    Oui c'est assez gros, mais comme c'est stocké dans une table de hachage, l'accès est rapide. Les tables de hachage sont présentes dans la librairie standard de beaucoup de langages: HashMap en Java, hash_map dans la STL (C++). Je ne connais pas Objective C, mais apparemment ça existe aussi (NSDictionary). Sauf en C, qui ne possède pas grand chose comme conteneur standard
    OK.
    Je ne veux pas utiliser l'objective C dans ce traitement. Je vais devoir construire une table de hash en C. Mais j'ai vu des exemples assez claires pour que je m'y retrouve.
    Merci.

Discussions similaires

  1. rechercher une sous chaine dans une chaine
    Par id.prog dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 25/01/2009, 17h59
  2. Rechercher une sous chaine dans un chaine
    Par franck06 dans le forum Access
    Réponses: 2
    Dernier message: 20/09/2006, 14h53
  3. Recherche une sous-chaine dans un champ ?
    Par nerick dans le forum Requêtes
    Réponses: 3
    Dernier message: 06/03/2006, 13h46
  4. Rechercher une sous chaine dans une chaine
    Par annedjomo dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 04/02/2005, 10h36
  5. Rechercher une sous chaine dans une chaine
    Par Oluha dans le forum ASP
    Réponses: 4
    Dernier message: 03/02/2005, 14h39

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