Modificação do gerador de texto para número de

telefone. Se você tiver um dicionário computadorizado

à disposição, modifique o programa que escreveu no

Exercício 11.13 para pesquisar as palavras no dicionário.

Algumas combinações de oito letras criadas por esse programa

consistem em duas ou mais palavras (o número

de telefone 3663-5467 produz “ÉOMELHOR”).

Passo 1

Para este exercício, precisaremos de um arquivo que contenha palavras de um dicionário. Digamos que esse arquivo seja chamado dictionary.txt para fins de demonstração. As palavras neste arquivo são alfabéticas e minúsculas.

Para determinar se nossa palavra é uma palavra ou um conjunto de duas ou mais palavras do dicionário, precisaremos de uma função recursiva que irá iterar pelos caracteres de nossa palavra, anexando uma substring que será comparada às palavras do dicionário.

Para fazer isso, usaremos funções:

fseek() - define a posição do arquivo do fluxo

feof() - testa o indicador EOF (se o arquivo chegar ao final do arquivo - EOF)

clearerr() - remove o sinalizador EOF do fluxo

Primeiro, vamos desenvolver o algoritmo que determina se uma palavra é uma palavra ou um conjunto de palavras no dicionário.

A função irá iterar pelos caracteres da palavra, acrescentando uma substring menor a cada iteração.

A cada iteração, compararemos a string com as palavras do dicionário.

Se uma substring for uma palavra, chame recursivamente a função para iterar a partir da próxima posição, criando uma nova substring.

A comunicação entre as funções serão indicadores falso/verdadeiro (0/1) indicando se uma palavra foi encontrada.

Passo 2

A função vai passar o valor do índice da posição inicial, a palavra calculada a partir do número e o dicionário.

Estaremos iterando do índice para NUM_SIZE - 1 (comprimento da palavra subtraído pelo elemento de caractere nulo).

int search(int index, char word[], FILE* dictionary)

{

char tmpWord[NUM_SIZE];

for (int i = index, j = 0; i

{

tmpWord[j] = tolower(word[i]);

tmpWord[j + 1] = '\0';

...

}

...

}

Em seguida, defina o ponteiro de arquivo do dicionário para o início do arquivo.

Leia palavras do dicionário até o final do arquivo. A palavra mais longa no dicionário de inglês tem 45 letras, portanto, o tamanho do buffer será 45 + o caractere nulo.

int search(int index, char word[], FILE* dictionary)

{

...

for (int i = index, j = 0; i

{

...

fseek(dictionary, 0, SEEK_SET);

do

{

char dictWord[46];

fscanf(dictionary, "%s", dictWord);

...

} while (!feof(dictionary));

...

}

...

}

Passo 3

Se a substring e uma palavra do dicionário corresponderem, chame recursivamente a função passando a próxima posição do índice.

A função retorna 1 se a substring correspondente tiver o último elemento de índice, o que significa que a palavra (e as substrings anteriores) correspondem a uma palavra do dicionário.

int search(int index, char word[], FILE* dictionary)

{

...

for (int i = index, j = 0; i

{

...

do

{

...

if (strcmp(tmpWord, dictWord) == 0)

{

if (i == NUM_SIZE - 2 ||

search(i + 1, word, dictionary))

return 1;

break;

}

} while (!feof(dictionary));

...

}

...

}

Após cada iteração, verifique se o ponteiro do arquivo de dicionário atingiu o final do arquivo. Limpe o sinalizador EOF se o fez.

Se o loop principal não resultou no retorno de 1, ele retornará 0:

int search(int index, char word[], FILE* dictionary)

{

...

for (int i = index, j = 0; i

{

...

if (feof(dictionary))

{

clearerr(dictionary);

}

}

return 0;

}

Agora, vamos fazer uma função que irá iterar através das palavras geradas a partir do número e passá-las para a função search().

Defina o ponteiro do arquivo para o início do arquivo.

Leia uma palavra do banco de dados e passe-a para a função search(). Se a função retornar 1, significa que a palavra ou o conjunto de palavras corresponde à(s) palavra(s) do dicionário. Assim, imprima essas palavras no console.

void findWords(FILE* file, FILE* dictionary)

{

fseek(file, 0, SEEK_SET);

do

{

char* word = (char*)malloc(NUM_SIZE);

fscanf(file, "%s", word);

if (search(0, word, dictionary))

printf("%s\n", word);

} while (!feof(file));

clearerr(file);

}

A implementação na função main():

int main()

{

char* num = (char*)malloc(NUM_SIZE);

printf("Enter a number (default format XXX-XXXX) >> ");

scanf("%s", num);

formatNumber(num);

char** formatedNum = extractArray(num);

FILE* outFile = fopen("words.dat", "w+");

computeCombinations(0, formatedNum,

(char*)malloc(ROW), outFile);

printf("Words generated successfully!\n");

// implementation

FILE* inFile = fopen("dictionary.txt", "r");

findWords(outFile, inFile);

fclose(outFile);

fclose(inFile);

return 0;

}

Resposta

Ver o desenvolvimento.