[C++]Creare parole con tasti telefono

TheBestNapoli
Salve a tutti, devo fare un programma in C++ che deve generare tutte le possibili parole da una sequenza di numeri corrispondenti a quelli di un telefonino; mi spiego meglio... come tutti sappiamo sui telefonini a ogni numero da 2 a 9 corrispondono 3 o 4 lettere:

il programma che devo implementare mi deve permettere di inserire da tastiera una sequenza di 7 numeri, dopodichè in base allo schema che ho scritto sopra mi deve generare tutte le possibili parole di 7 lettere che si possono generare con quella sequenza; il numero di parole è elevato ($3^7=2187$) e quindi devono essere memorizzate su un file. Es. (con 2 cifre)

Spero di aver inteso lo scopo di questo programma; ora per quanto riguarda la sua soluzione qualcuno potrebbe consigliarmi qualche approccio? E' la prima volta che affronto programmi di questo tipo e vorrei riuscire a capire come affrontarli. Grazie mille a tutti.

Risposte
Summerwind78
Praticamente vuoi fare ció che fa il T9 nei cellulari?

Ti servono tutte le ponsibili combinazioni o soloquelle che formano parole corrette?

TheBestNapoli
tutte quante... anche quelle che non hanno senso compiuto

apatriarca
Il metodo più semplice, conoscendo la lunghezza della sequenza di numeri, è quella di fare 7 cicli annidati i cui rispettivi contatori determinano la lettera che viene stampata ad una certa posizione. Non è però un metodo molto flessibile. Alternativamente si può utilizzare un metodo ricorsivo in cui uno dei parametri rappresenta la posizione attuale nella sequenza e in cui viene costruita gradualmente la parola. Il seguente codice ne è un esempio:
#include <fstream>
#include <iostream>
#include <string>

std::string const letters[10] = { "", "", "ABC", "DEF", "GHI", "JKL", "MNO", "PQRS", "TUV", "WXYZ" };

void print_words_rec(int numbers[], int n, char temp[], int i, std::fstream &out)
{
    if (i < n) {
        const std::string &s = letters[numbers[i]];

        for (register unsigned j = 0; j < s.size(); ++j) {
            temp[i] = s.at(j);
            print_words_rec(numbers, n, temp, i+1, out);
        }
    } else {
        temp[i] = '\0';
        out << temp << std::endl;
    }
}

void print_words(int numbers[], int n, std::fstream &out)
{
    char *temp = new char[n+1];
    print_words_rec(numbers, n, temp, 0, out);
}

int main()
{
    std::fstream out("./prova.txt", std::fstream::out);
    if (!out) {
        std::cout << "Impossibile creare il file.\n";
    }

    int numbers[] = {3, 4, 5, 2, 5, 6, 9, 7, 8};

    print_words(numbers, sizeof(numbers)/sizeof(int), out);

    out.close();
}

Si può anche riscrivere questo programma ricorsivo in forma iterativa, ma per un programma così semplice non credo che ne valga molto la pena.

TheBestNapoli
Ciao, grazie mille per aver risposto... in realtà anche io avevo pensato ai 7 cicli però non sapevo come implemetarli, se puoi potresti farmi vedere come avrei potuto fare questo programma in forma iterativa? :lol:
Per quanto riguarda la forma ricorsiva leggendo il programma sono riuscito a capire più o meno tutti i passaggi tranne 2 cose (forse banalissime):
out< e poi nel main:
print_words(numbers, sizeof(numbers)/sizeof(int), out); perchè usi sizeof(numbers)/sizeof(int) ?
Grazie ancora per la pazienza. :lol:

apatriarca
out<
Perché la funzione entra nell'else quando la parola è completa. Ad ogni livello di ricorsione si aggiunge una lettera.

perchè usi sizeof(numbers)/sizeof(int)?

sizeof(numbers) è la dimensione in byte dell'array, dividendo per sizeof(int), cioè la dimensione in byte degli int, si ottiene quindi il numero di elementi dell'array.

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.