Page 3 sur 4

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

Publié : 26 Jan 2020 14:44
par EmileF
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.

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

Publié : 26 Jan 2020 15:03
par Alesk
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.

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

Publié : 26 Jan 2020 15:31
par EmileF
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

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

Publié : 26 Jan 2020 15:39
par Alesk
Donc tu ferais bien d'opérer la modif que je viens de te décrire, ça réduira drastiquement les recherches inutiles.

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

Publié : 26 Jan 2020 16:23
par EmileF
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

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

Publié : 26 Jan 2020 16:41
par Alesk
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.

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

Publié : 27 Jan 2020 02:25
par djulio74
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 ^^

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

Publié : 27 Jan 2020 12:24
par EmileF
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:

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

Publié : 27 Jan 2020 14:09
par EmileF
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.

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

Publié : 27 Jan 2020 14:15
par djulio74
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. ^^