Suggeritore di parole per UpWords

di il
7 risposte

Suggeritore di parole per UpWords

Ciao,

sto implementando un suggeritore di parole per il gioco UpWords. Da specifiche mi vengono date in un turno 7 lettere e devo essere in grado di elaborare il miglior suggerimento utilizzando le lettere date più quelle di una parola presente già nel campo da gioco (posso modificarla lasciando almeno un carattere).

Ho deciso di implementare una funzione che mi calcoli tutte le combinazioni possibili di n (7 lettere più quelle della parola presa in considerazione) caratteri in k spazi.

Quindi ho un lungo elenco di combinazioni: abcdefghie ... abcdefghi ... abcdefg ... abcde ... abc... e così via...

La funzione purtroppo risulta già un po' lenta nell'elaborazione di tutte le combinazioni (test con combinazioni di 11 caratteri in k spazi k [11,2])

Questo è il codice per la preparazione delle combinazioni:
void anagrammi(const string &lettere, const vector<unsigned int> &v, vector<string> &parole)
{
    string s;
    for(unsigned int i = 0; i < v.size(); ++i)
    {
        s.push_back(lettere[v[i]]);
    }
    do
    {
        parole.push_back(s);
    }
    while(next_permutation(s.begin(), s.end()));
}

void combinazioni(string lettere, vector<string> &parole)
{
    vector<unsigned int> v;
    unsigned int i;
    unsigned int j;
    bool flag;
    sort(lettere.begin(), lettere.end());
    for(unsigned int k = lettere.size(); k > 1; --k)
    {
        v.resize(0);
        i = k - 1;
        flag = true;
        for(j = 0; j < k; ++j)
        {
            v.push_back(j);
        }
        while(true)
        {
            if(flag)
            {
                anagrammi(lettere, v, parole);
                flag = false;
            }
            if(v[i] < i + lettere.size() - k)
            {
                ++v[i];
                flag = true;
                if(i != k - 1 && v[i] != v[i + 1] - 1)
                {
                    for(j = i + 1; j < k; ++j)
                    {
                        v[j] = v[j - 1] + 1;
                    }
                    i = k - 1;
                }
            }
            else
            {
                if(i)
                {
                    --i;
                }
                else
                {
                    break;
                }
            }
        }
    }
}
Pensavo poi di eliminare da tali combinazioni tutte quelle in cui le lettere che compongono la parola non sono nella posizione iniziale... per spiegarmi meglio... se ho le tra le lettere disponibili E,A,C,S,M,U,O e la parola nel campo da gioco prese in considerazione è CANE io posso utilizzare le lettere già presenti della parola CANE cambiarne alcun con le lettere che ho a disposizione ma senza cambiare l'ordine di quelle che rimangono...
Una parola che posso comporre sarà quindi "esAmE" composta sostituendo la C e la N di cane con la S e la M che ho a disposizione e aggiungendo davanti la E

Io avevo pensato ad una funzione che passasse in entrata un puntatore al vettore di combinazioni...
char temp_char;
    bool check=false;
    for (int i=0; i<allComb->size(); i++){
        check=false;
        for (int k=0; k<allComb->at(i).size(); k++){
            if (check){
                if (allComb->at(i)[k]>='h'){
                    if (allComb->at(i)[k]==temp_char+1){
                        temp_char++;
                    } else {
                        allComb->erase(allComb->begin()+i);
                        break;
                    }
                }
                if (allComb->at(i)[k]<'h'){
                    temp_char++;
                }
            }
            if (!check){
                if (allComb->at(i)[k]>='h'){
                    temp_char=allComb->at(i)[k];
                    check=true;
                }
            }
      
L'esecuzione però mi risulta parecchio lenta e non riesco a capirne il motivo...

7 Risposte

  • Re: Suggeritore di parole per UpWords

    Potresti fare qualche ulteriore esempio di lettere disponibili, parola data e miglior suggerimento?
    In particolare non ho ben capito cosa si intende con miglior suggerimento.
  • Re: Suggeritore di parole per UpWords

    Con miglior suggerimento mi riferisco ad una funzione che sarà poi da implementare e che tra tutti i suggerimenti elaborati selezionerà quello che permette di ottenere il punteggio più alto! (ogni parola ha un suo punteggio calcolato in base alla posizione e al numero di lettere aggiunte o sostituite)
  • Re: Suggeritore di parole per UpWords

    Dimmi se ho capito bene, considerando l'esempio che hai fatto, alla funzione combinazioni() passi la stringa "EACSMUOCANE", giusto?

    Quindi cosa stai chiedendo precisamente in questo topic?
  • Re: Suggeritore di parole per UpWords

    Con una prima funzione io elaboro tutte le combinazioni di n caratteri in n spazi...
    ipotizzando che i caratteri siano 9 (abcdefghi) calcolo tutte le permutazioni. Proseguo calcolando tutte le possibili combinazioni degli stessi caratteri in k spazi (dove k è n-1). Terminato anche questo calcolo si ripete decrementando k fino a quando è uguale a 2.

    A questo punto in un'ipotetica stringa abcdefghi, i primi 7 caratteri sono quelli che ho a disposizione per creare una nuova parola mentre i seguenti sono quelli che compongono la parola che ho già nel campo da gioco...

    In pratica mi sono bloccato sulla funzione che mi consenta di fare in modo che in ogni stringa se incontro un carattere = o > di h quello successivo dovrà essere uguale al carattere +1 o uno di quelli < di 'h'... Tutte quelle che non soddisfano la condizione vengono già eliminate... questo perché le lettere posizionate sul campo da gioco possono essere sostituite con una di quelle nuove ma non possono essere riutilizzate spostandole...

    Il problema è che sia la funzione che mi calcola le combinazioni sia questa che mi elimina quelle non idonee sono molto lente nell'esecuzione... mi chiedevo se c'erano soluzioni alternative o accorgimenti da prendere per velocizzare il procedimento...
  • Re: Suggeritore di parole per UpWords

    Con una prima funzione io elaboro tutte le combinazioni di n caratteri in n spazi...
    ipotizzando che i caratteri siano 9 (abcdefghi) calcolo tutte le permutazioni. Proseguo calcolando tutte le possibili combinazioni degli stessi caratteri in k spazi (dove k è n-1). Terminato anche questo calcolo si ripete decrementando k fino a quando è uguale a 2.
    Questo lo so dal momento che quelle funzioni le ho scritte io!
    A questo punto in un'ipotetica stringa abcdefghi, i primi 7 caratteri sono quelli che ho a disposizione per creare una nuova parola mentre i seguenti sono quelli che compongono la parola che ho già nel campo da gioco...
    Quindi la risposta alla mia precedente domanda è sì?
    In pratica mi sono bloccato sulla funzione che mi consenta di fare in modo che in ogni stringa se incontro un carattere = o > di h quello successivo dovrà essere uguale al carattere +1 o uno di quelli < di 'h'... Tutte quelle che non soddisfano la condizione vengono già eliminate... questo perché le lettere posizionate sul campo da gioco possono essere sostituite con una di quelle nuove ma non possono essere riutilizzate spostandole...
    Più o meno ho capito il senso, ma mi chiedo, sei sicuro che quella che stai seguendo sia la strada migliore per raggiungere l'obiettivo prefissato?!
    Inoltre immagino che le parole debbano avere un senso, o sbaglio? Hai per caso un database con tutte le parole della lingua italiana?
  • Re: Suggeritore di parole per UpWords

    Hai ragione!! Perdonami non ricordavo il nickname!

    Dunque io calcolo tutte le combinazioni con le lettere nell’ordine alfabetico e solo dopo aver fatto quel passaggio di esclusione le sostituisco con quelle che ti ho scritto nell’esempio...
    Questo perché ho organizzato le lettere che ho a disposizione utilizzando una classe dedicata chiamata Letter perché purtroppo devo riuscire a gestire anche “Qu” che nel gioco vale come se fosse “A” “B” “U” ...

    Esatto poi devo escludere anche quelle che, dopo opportuna verifica sul dizionario (file txt che ho già), non hanno significato

    Sul fatto che sia la strada migliore ho qualche dubbio... mi sembra di dover scorrere tante volte questo vettore che contiene parecchi elementi e ciò significa peccare suo tempo di esecuzione che è infatti notevole!
    Hai qualche suggerimento su una strada migliore?

    Grazie mille!!
  • Re: Suggeritore di parole per UpWords

    Premesso che non ho mai affrontato l'argomento file in C/C++ e che non conosco le specifiche del programma che vuoi creare, e quindi non so se la mia idea sia fattibile dal punto di vista pratico. In ogni caso farei nel seguente modo:
    - dal momento che ti interessa solo il miglior suggerimento (o i migliori suggerimenti nel caso in cui esistano più parole con lo stesso punteggio massimo), prenderei in considerazione una singola parola per volta a partire da quelle a maggior punteggio;
    - per ogni lettera aggiunta dopo la prima inoltre andrei a controllare se esistono parole di senso compiuto nel "vocabolario" di riferimento.
Devi accedere o registrarti per scrivere nel forum
7 risposte