[Resolu][MY-AL]Recherche de mots dans dico

Pour les scripts écrits en C#
Règles du forum
Merci de respecter la NOMENCLATURE suivante pour vos TITRES de messages :

Commencez par le niveau de vos scripts
DB = Débutant
MY = Moyen
CF = Confirmé

Puis le domaine d'application
-RS = Réseau
-AL = Algorithmie

Exemple :

[DB-RS] Mouvement perso multijoueur
EmileF
Messages : 501
Inscription : 18 Mars 2017 19:39

Re: [Resolu][MY-AL]Recherche de mots dans dico

Message par EmileF » 26 Jan 2020 14:44

Aelhan a écrit :Sinon tu as des sites d'upload de fichiers, dont tu peux partager le lien (les moteurs de recherche proposent plein de résultats, avec validité du fichier d'une semaine en version gratuite souvent : https://www.qwant.com/?q=upload+fichier ... opensearch)
Ok, merci, je verrai si ça ne marche pas.
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

Avatar de l’utilisateur
Alesk
Messages : 2296
Inscription : 13 Mars 2012 09:09
Localisation : Bordeaux - France
Contact :

Re: [Resolu][MY-AL]Recherche de mots dans dico

Message par Alesk » 26 Jan 2020 15:03

EmileF a écrit :
26 Jan 2020 11:37
Alesk, Merci pour ton message

Je ne vois pas très bien comment je peux adapter ton dico à mes recherches, sachant que je recherche mes mots par rapport au début du mot, pas par rapport au mot complet.

Mon dico est classé par ordre alphabétique et automatiquement par ordre de taille. Et j'utilise les ReGex pour faire mes recherches. Par contre pour faire des recherches d'anagrammes par exemple ça me semble idéal, j'ais déjà fait un truc dans ce genre à une certaine époque.
Ok ! Bon j'avais pas tout compris non plus :p
Mais quand tu fais une RegEx, tu la fait sur tout ton dictionnaire ? ou bien juste sur une portion ?
Parce que pour optimiser, la première chose à faire est d'éliminer tous les cas où tu seras sûr que ça ne collera pas.
Par exemple, si tu cherche un mot commençant par "Gu", ça ne sert à rien d'exécuter ta RegEx sur les mots commençant par autre chose que ces deux lettres.
Un tri simple à faire, serait de classer tes mots par ordre alphabétique, mais sur plusieurs niveaux, par exemple, sur la 1ere lettre, puis un second niveau sur la deuxième lettre, et un dernier niveau sur la troisième lettre, pas besoin d'aller plus loin je pense pour grandement réduire la quantité de mots à tester avec ton expression régulière.

EmileF
Messages : 501
Inscription : 18 Mars 2017 19:39

Re: [Resolu][MY-AL]Recherche de mots dans dico

Message par EmileF » 26 Jan 2020 15:31

Alesk a écrit :Mais quand tu fais une RegEx, tu la fait sur tout ton dictionnaire ? ou bien juste sur une portion ?
Je fais mes recherches sur la totalité du dico à la première lettre et ensuite sur la portion que j'extraits à chaque fois.
La liste se réduit donc au fur et à mesure de la recherche qui s'arrête quand la liste est vide
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

Avatar de l’utilisateur
Alesk
Messages : 2296
Inscription : 13 Mars 2012 09:09
Localisation : Bordeaux - France
Contact :

Re: [Resolu][MY-AL]Recherche de mots dans dico

Message par Alesk » 26 Jan 2020 15:39

Donc tu ferais bien d'opérer la modif que je viens de te décrire, ça réduira drastiquement les recherches inutiles.

EmileF
Messages : 501
Inscription : 18 Mars 2017 19:39

Re: [Resolu][MY-AL]Recherche de mots dans dico

Message par EmileF » 26 Jan 2020 16:23

C'est ce que je fais dans mon script je crois.
je crée une liste des mots commençant par mes 2 premières lettres.
Ensuite dans cette liste, je récupère ceux qui contiennent aussi la 3ème lettre
et ainsi de suite jusqu'à ce que ma liste soit vide ou que je ne trouve plus d'occurence.
Au fur et à mesure de ma recherche je verifie les mots qui sont complet et je les stocke comme mots trouvés
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

Avatar de l’utilisateur
Alesk
Messages : 2296
Inscription : 13 Mars 2012 09:09
Localisation : Bordeaux - France
Contact :

Re: [Resolu][MY-AL]Recherche de mots dans dico

Message par Alesk » 26 Jan 2020 16:41

Ce que je voulais dire c'est que ton dictionnaire doit déjà être organisé comme ça à la base, afin d'éviter d'avoir à regénérer ce tri à chaque recherche.

djulio74
Messages : 491
Inscription : 19 Déc 2009 22:55
Contact :

Re: [Resolu][MY-AL]Recherche de mots dans dico

Message par djulio74 » 27 Jan 2020 02:25

Je reviens vers toi même si tu as mis le sujet en résolu.
tu cherchais à optimiser le temps de recherche, me suis un peu plus penché sur le sujet, en gardant mon idée de travailler sur des array de int plutot que manipuler les string.

J'ai donc utiliser ton dico, ta grille de base basé sur "anticonstitutionnellement", de 5x5,

je te met le script, pas eu le temps de l'annoté mais pour faire bref, temps total de 0,5s pour lire le dico, convertir en array de array de int, et faire le recherche des mots basé sur les 8 directions, donnant un total de 944 mots trouvé dans le dico.
seul serait a rajouter une condition car trouve plusieurs fois le même mot parfois.
le recherche seule, en appuyant sur "r" se fait en 0.15s, en sortant la liste des mots.

Code : Tout sélectionner

using System;
using System.Collections.Generic;
using UnityEngine;
using System.Text;
using System.IO;

public class TestMots : MonoBehaviour
{

	private string DICOpath = "C:/Users/djuli/Documents/dico.txt";

	private string[] Dictionnaire;
	private int[][] DicoNumérique;
	private int[] MotsFinal;
	private int MotsFinalCount;

	private int TailleGrille = 5;
	private int[] grille;
	private int[] dir;

	void Start ()
	{
		float tp = Time.realtimeSinceStartup;
		InitialiseGrille ();
		InitialiseDico ();
		PrintGrille ();
		RechercheMot ();
		tp = Time.realtimeSinceStartup - tp;
		print ( tp);
	}

	void Update ()
	{

		if (Input.GetKeyDown ("r")) {
			float tp = Time.realtimeSinceStartup;
			RechercheMot ();
			tp = Time.realtimeSinceStartup - tp;
			print (tp);
			// print les motes trouvés
			for (int i = 0; i < MotsFinalCount; i++) {
				print (Dictionnaire [MotsFinal [i]]);
			}
		}
	}

	void InitialiseGrille ()
	{

		grille = new int[TailleGrille * TailleGrille];
		char[] A = "ANTICONSTITUTIONNELLEMENT".ToCharArray ();
		for (int i = 0; i < TailleGrille; i++) {
			for (int j = 0; j < (TailleGrille + 1) / 2; j++) {
				grille [i + 2 * j * TailleGrille] = char.ToUpper (A [i + 2 * j * TailleGrille]) - 64;
			}
		}
		for (int i = 0; i < TailleGrille; i++) {
			for (int j = 0; j < TailleGrille / 2; j++) {
				grille [(j + 1) * 2 * TailleGrille - 1 - i] = char.ToUpper (A [(2 * j + 1) * TailleGrille + i]) - 64;
			}
		}
		dir = new int[8] {
			1,
			1 + TailleGrille,
			TailleGrille,
			TailleGrille - 1,
			-1,
			-1 - TailleGrille,
			-TailleGrille,
			1 - TailleGrille
		};
	}

	void InitialiseDico ()
	{

		if (File.Exists (DICOpath) == true) {
			StreamReader dico = File.OpenText (DICOpath);
			Dictionnaire = dico.ReadToEnd ().Split ("\n" [0]);
			Debug.LogError ("Dictionnaire trouvé  :" + Dictionnaire.Length + " mots");
		} else {
			Debug.LogError ("Attention dictionnaire non trouvé");
			return;
		}
		DicoNumérique = new int[Dictionnaire.Length][];
		for (int i = 0; i < Dictionnaire.Length; i++) {
			DicoNumérique [i] = new int[Dictionnaire [i].Length - 1];
			for (int j = 0; j < Dictionnaire [i].Length - 1; j++) {
				DicoNumérique [i] [j] = char.ToUpper (Dictionnaire [i] [j]) - 64;
			}
		}
	}

	void PrintGrille ()
	{

		char[] alphabet = "abcdefghijklmnopqrstuvwxyzé".ToCharArray ();

		for (int i = 0; i < TailleGrille; i++) {	
			string ligne = "";
			for (int j = 0; j < TailleGrille; j++) {
				ligne += char.ToUpper (alphabet [grille [i * TailleGrille + j] - 1]).ToString () + " ";
			}
			print (ligne);
		}
	}

	void RechercheMot ()
	{
		MotsFinal = new int[10];
		MotsFinalCount = 0;
		int[] MotsBase = new int[DicoNumérique.Length];
		for (int i = 0; i < MotsBase.Length; i++) {
			MotsBase [i] = i;
		}

		for (int i = 0; i < grille.Length; i++) {			
			MotAvecLettre (0, i, MotsBase);
		}
	}

	void MotAvecLettre (int pos, int Case, int[] mots)
	{
		int MotsTrouvésCount = 0;
		int[] MotsTrouvés = new int[mots.Length];
		int lettre = grille [Case];

		for (int i = 0; i < mots.Length; i++) {
			if (DicoNumérique [mots [i]].Length > pos && DicoNumérique [mots [i]] [pos] == lettre) {
				MotsTrouvés [MotsTrouvésCount] = mots [i];
				MotsTrouvésCount++;
			}
			if (DicoNumérique [mots [i]].Length == pos + 1 && DicoNumérique [mots [i]] [pos] == lettre) {
				
				MotsFinal [MotsFinalCount] = mots [i];
				MotsFinalCount += 1;
				if (MotsFinal.Length == MotsFinalCount) {
					Array.Resize (ref MotsFinal, MotsFinalCount + 10);
				}
			}
		}
		Array.Resize (ref MotsTrouvés, MotsTrouvésCount);

		if (MotsTrouvésCount > 0) {
			
			for (int i = 0; i < dir.Length; i++) {
				int CaseSuivante = Case + dir [i];
				int colonne = (Case) % TailleGrille + dir [i] % TailleGrille;
				int ligne = (CaseSuivante) / TailleGrille;

				if ( ligne >= 0 && ligne < TailleGrille && colonne >= 0 && colonne < TailleGrille && CaseSuivante >= 0 && CaseSuivante < TailleGrille * TailleGrille) {
					MotAvecLettre (pos + 1, CaseSuivante, MotsTrouvés);
				
				}
			}
		}
	}
}
Voilà je te laisse potasser si tu veux, et si t'as des questions de fonctionnement, j'aurai plus de temps demain pour y répondre.
allez bonne nuit ^^

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

EmileF
Messages : 501
Inscription : 18 Mars 2017 19:39

Re: [Resolu][MY-AL]Recherche de mots dans dico

Message par EmileF » 27 Jan 2020 12:24

He oui, j'avais réglé mon problème en mettant une barre de progression pour faire patienter.
Mais ton script m'interresse, et je vais l'étidier de près immédiatement.

En tout cas merci Djulio. Je suis allé voir tes réalisations, c'est extrêmement pointu, c'est dommage que ce ne soit pas dans mon genre de jeu. Tu partages volontiers et il y a beaucoup à apprendre de toi.
J'aimerai que tu prennes le temps d'aller voir AbouSimbel
viewtopic.php?f=12&t=17295

ton avis me serait très précieux.

J'ai du boulot, j'y vais :mrgreen:
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

EmileF
Messages : 501
Inscription : 18 Mars 2017 19:39

Re: [Resolu][MY-AL]Recherche de mots dans dico

Message par EmileF » 27 Jan 2020 14:09

Bon, Djulio, voilà:

Pour la vitesse 0.1....Nickel:
Pour la liste, beaucoup de doubles, je vais essayer de voir à cause de quoi, Il y a des doubles dans le dictionnaire.
Mais il n'y a pas de mots de plus de 12 caractères. C'est voulu?

Pourquoi le "é" à la fin de l'alphabet ?

Code : Tout sélectionner

        
        char[] alphabet = "abcdefghijklmnopqrstuvwxyzé".ToCharArray();
J'ai utilisé mon dico en textAsset
J'ai été obligé d'ajouter -1 à 2 boucles for pour éviter des blocages, je n'ai pas compris pourquoi.

Code : Tout sélectionner

        
        Dictionnaire = dico.text.Split("\n"[0]);

        DicoNumerique = new int[Dictionnaire.Length][];
        for (int i = 0; i < Dictionnaire.Length - 1; i++)
        {
            DicoNumerique[i] = new int[Dictionnaire[i].Length - 1];
            for (int j = 0; j < Dictionnaire[i].Length - 1; j++)
            {
                DicoNumerique[i][j] = char.ToUpper(Dictionnaire[i][j]) - 64;
            }
        }
et

Code : Tout sélectionner

    void MotAvecLettre(int pos, int Case, int[] mots)
    {
        int MotsTrouvésCount = 0;
        int[] MotsTrouvés = new int[mots.Length];
        int lettre = grille[Case];

        for (int i = 0; i < mots.Length - 1; i++)
        {
            if (DicoNumerique[mots[i]].Length > pos && DicoNumerique[mots[i]][pos] == lettre)
            {
                MotsTrouvés[MotsTrouvésCount] = mots[i];
                MotsTrouvésCount++;
            }
            if (DicoNumerique[mots[i]].Length == pos + 1 && DicoNumerique[mots[i]][pos] == lettre)
            {

                MotsFinal[MotsFinalCount] = mots[i];
                MotsFinalCount += 1;
                if (MotsFinal.Length == MotsFinalCount)
                {
                    Array.Resize(ref MotsFinal, MotsFinalCount + 10);
                }
            }
        }
        Array.Resize(ref MotsTrouvés, MotsTrouvésCount);

        if (MotsTrouvésCount > 0)
        {

            for (int i = 0; i < dir.Length; i++)
            {
                int CaseSuivante = Case + dir[i];
                int colonne = (Case) % TailleGrille + dir[i] % TailleGrille;
                int ligne = (CaseSuivante) / TailleGrille;

                if (ligne >= 0 && ligne < TailleGrille && colonne >= 0 && colonne < TailleGrille && CaseSuivante >= 0 && CaseSuivante < TailleGrille * TailleGrille)
                {
                    MotAvecLettre(pos + 1, CaseSuivante, MotsTrouvés);
                }
            }
        }
    }
Mais c'est déjà super.
Dernière édition par EmileF le 27 Jan 2020 14:18, édité 1 fois.
La différence entre l'intelligence et la stupidité est que l'intelligence est limitée.

djulio74
Messages : 491
Inscription : 19 Déc 2009 22:55
Contact :

Re: [Resolu][MY-AL]Recherche de mots dans dico

Message par djulio74 » 27 Jan 2020 14:15

alors oui il y a des doubles mais je suis en train de voir pourquoi, ma condition pour la viabilité des 8 directions est incorrecte.

Entonnant que tu n'ai rien de plus de 12 caractères, moi il me trouve bien "anticonstitutionnellement" même plusieurs fois a cause de l’erreur. normalement au début de la liste tu trouve bien les longs mots en A. tu as bien laissé le TailleGrille à 5?
Par contre dans ton dico tu as des mots de une seul lettre comme le c

simple faute de frappe pour l'alphabet. ^^

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

Répondre

Revenir vers « (C#) CSharp »