Gerador de texto para número de telefone. Os

teclados-padrão de telefone contêm os dígitos de 0 a 9.

Os números de 2 a 9 possuem três letras associadas a

cada um deles, conforme indicado pela tabela a seguir:

Muitas pessoas acham difícil decorar números de telefone,

por isso associam os dígitos a palavras de oito letras

que correspondam aos números de telefone. Por exemplo,

uma pessoa cujo número de telefone 3663-2272 poderia

usar a tabela acima e associar seu telefone à palavra

de sete letras “FONECASA”.

Constantemente, empresas tentam obter números de

telefone que sejam facilmente lembrados por seus clientes.

Então, se uma empresa puder anunciar uma palavra

simples que seus clientes possam ‘digitar’, sem dúvida, a

empresa receberá mais chamadas.

Cada palavra de oito letras corresponde a exatamente

um número de telefone de oito dígitos. O restaurante

que deseja aumentar seus negócios de pedido por telefone

pode, certamente, fazer isso com o número 3686-

3427(ou seja, “ENTREGAS”).

Cada número de telefone de oito dígitos corresponde a

muitas palavras de oito letras separadas. Infelizmente,

a maior parte delas representa justaposições irreconhecíveis

de letras. É possível, porém, que o proprietário

de um salão de cabeleireiro fique satisfeito em saber

que o número de telefone 2662-6683 corresponde a

“BOMCORTE”. O proprietário de uma loja de bebidas,

sem dúvida, poderia ficar feliz sabendo que o número de

telefone da loja, 2378-3527, corresponde a “CERVEJAS”.

Escreva um programa em C que, dado um número de

oito dígitos, grave em um arquivo cada palavra de oito

letras possível que corresponda a esse número. Existem

2187 (3 à sétima potência) dessas palavras. Evite números

de telefone com os dígitos 0 e 1.

Passo 1

Vamos criar um programa que calcula cada palavra possível que corresponda ao número dado.

Essencialmente, vamos extrair um array 2D composto por letras correspondentes aos dígitos do número, a partir do qual geraremos palavras.

O algoritmo que usaremos utiliza a chamada de função recursiva.

É sempre uma boa prática tornar um programa escalável a partir de um ponto no programa, o cabeçalho.

Para começar, vamos definir constantes que correspondam às especificações do tamanho do número que usaremos ao longo do programa.

#include

#include

#define NUM_SIZE 9

#define ROW (NUM_SIZE - 2)

#define COL 3

Passo 2

Adicione a matriz da tabela de letras de dígitos (tabela indicada pela tarefa):

char table[8][3] = {

'A', 'B', 'C',

'D', 'E', 'F',

'G', 'H', 'I',

'J', 'K', 'L',

'M', 'N', 'O',

'P', 'R', 'S',

'T', 'U', 'V',

'W', 'X', 'Y'

};

Em primeiro lugar, nosso objetivo será extrair a matriz 2D exata que corresponde ao número.

Por exemplo, o número 27 resultará na seguinte matriz 2D:

{ 'A', 'B', 'C',

'P', 'R', 'S' }

Esse processo é feito para simplificar o código escrito na função que calcula as combinações.

Antes de extrair o array, temos que formatar o número (remover o traço).

Aqui, temos que assumir que qualquer que seja o tamanho do número, o traço é o 4º elemento.

Vamos removê-lo com a seguinte função que move os caracteres após o 4º elemento um elemento para trás (lembre-se que o último elemento das strings é '\0'):

void formatNumber(char num[NUM_SIZE])

{

for (int i = 3; i

{

num[i] = num[i + 1];

}

}

Em seguida, vamos extrair o array 2D correspondente ao número.

A função primeiro alocará memória para o array 2D da seguinte forma:

char** extractArray(char key[NUM_SIZE])

{

char** res = (char**)malloc(ROW * sizeof(char*));

for (int i = 0; i

res[i] = (char*)malloc(COL);

...

}

Então, vamos iterar pelo número, que vai determinar a linha da tabela (subtrair por 2 porque os elementos contam a partir de zero e os primeiros dados começam do número 2):

char** extractArray(char key[NUM_SIZE])

{

...

for (int i = 0; i

{

for (int j = 0; j

{

res[i][j] = table[key[i] - '0' - 2][j];

}

}

return res;

}

Agora, vamos desenvolver um algoritmo que irá calcular as combinações que precisamos.

A função irá iterar através de cada elemento de coluna vinculado a cada elemento de coluna de outras linhas. Assim, vamos calcular todas as combinações possíveis.

Ele rastreará a "profundidade" (linha atual), que usaremos para ver quando uma palavra chegar ao final da linha - o último caractere - indicando que a palavra foi gerada e está pronta para ser emitida.

Além disso, a função precisará passar uma string para si mesma, que anexará a cada iteração.

void computeCombinations(int depth, char** matrix,

char* output, FILE* outFile)

{

...

}

Para um elemento em uma coluna de linha de valor "profundidade", atribua à string de saída a letra:

void computeCombinations(int depth, char** matrix,

char* output, FILE* outFile)

{

for (int i = 0; i

{

output[depth] = matrix[depth][i];

...

}

}

Passo 3

Se a última linha não for alcançada, chame recursivamente a função aumentando a "profundidade" (linha):

void computeCombinations(int depth, char** matrix,

char* output, FILE* outFile)

{

for (int i = 0; i

{

...

if (depth

{

computeCombinations(depth + 1, matrix,

output, outFile);

}

...

}

}

Quando a última linha for alcançada, imprima a palavra:

void computeCombinations(int depth, char** matrix,

char* output, FILE* outFile)

{

for (int i = 0; i

{

...

if (depth == ROW - 1)

{

for (int j = 0; j

fprintf(outFile, "%c", output[j]);

fprintf(outFile, "\n");

}

}

}

Se quisermos ter certeza de que o algoritmo funciona, podemos adicionar um incremento de uma variável de contador inteiro estático global inicializada em zero após as instruções de saída para ver quantas palavras são geradas após a execução de um programa.

Se imprimirmos o valor do contador no final do programa, ele imprimirá 2187 para a entrada de números de sete dígitos.

static int counter = 0;

void computeCombinations(int depth, char** matrix,

char* output, FILE* outFile)

{

for (int i = 0; i

{

...

if (depth == ROW - 1)

{

for (int j = 0; j

fprintf(outFile, "%c", output[j]);

fprintf(outFile, "\n");

counter++;

}

}

}

Na função main(), solicite ao usuário que insira um número:

int main()

{

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

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

scanf("%s", num);

...

}

Formate o número (remova o traço) e extraia o array 2D:

int main()

{

...

formatNumber(num);

char** formatedNum = extractArray(num);

...

}

Abra o arquivo de saída:

int main()

{

...

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

...

}

Chame a função computeCombinations() da seguinte maneira - passando a profundidade zero e um buffer de string de saída com memória suficiente alocada:

int main()

{

...

computeCombinations(0, formatedNum,

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

...

}

Por fim, imprima uma mensagem e feche o arquivo:

int main()

{

...

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

fclose(outFile);

return 0;

}

Resposta

Ver o desenvolvimento.