Il modo in cui farei questo è creare una serie di indici della stessa lunghezza della stringa, tutti inizializzati a zero. Quindi consideriamo questa matrice di indici come un contatore per enumerare tutti i possibili mapping della nostra stringa sorgente. Un indice 0 mappa quella posizione nella stringa alla prima mappatura per quel carattere, un 1 al secondo, ecc. Possiamo attraversarli in ordine semplicemente incrementando l'ultimo indice dell'array, portandoci alla posizione successiva quando raggiungere il numero massimo di mappature per quella posizione.
Per usare il tuo esempio, abbiamo le mappature
'a' => 'e', 'o'
'b' => 'i'
Con la stringa di input "abba", abbiamo bisogno di un array di quattro elementi per i nostri indici:
[0,0,0,0] => "abba"
[0,0,0,1] => "abbe"
[0,0,0,2] => "abbo"
[0,0,1,0] => "abia"
[0,0,1,1] => "abie"
[0,0,1,2] => "abio"
[0,1,0,0] => "aiba"
[0,1,0,1] => "aibe"
[0,1,0,2] => "aibo"
[0,1,1,0] => "aiia"
[0,1,1,1] => "aiie"
[0,1,1,2] => "aiio"
[1,0,0,0] => "ebba"
[1,0,0,1] => "ebbe"
[1,0,0,2] => "ebbo"
[1,0,1,0] => "ebia"
[1,0,1,1] => "ebie"
[1,0,1,2] => "ebio"
[1,1,0,0] => "eiba"
[1,1,0,1] => "eibe"
[1,1,0,2] => "eibo"
[1,1,1,0] => "eiia"
[1,1,1,1] => "eiie"
[1,1,1,2] => "eiio"
[2,0,0,0] => "obba"
[2,0,0,1] => "obbe"
[2,0,0,2] => "obbo"
[2,0,1,0] => "obia"
[2,0,1,1] => "obie"
[2,0,1,2] => "obio"
[2,1,0,0] => "oiba"
[2,1,0,1] => "oibe"
[2,1,0,2] => "oibo"
[2,1,1,0] => "oiia"
[2,1,1,1] => "oiie"
[2,1,1,2] => "oiio"
Prima di iniziare la generazione di questi stringhe, avremo bisogno di un posto in cui archiviarle, che in C significa che dobbiamo allocare memoria. Fortunatamente, conosciamo già la lunghezza di queste stringhe e possiamo calcolare il numero di stringhe che genereremo: è solo il prodotto del numero di mapping per ciascuna posizione.
Mentre è possibile return them in an array, preferisco utilizzare un callback per restituirli come li trovo.
#include <string.h>
#include <stdlib.h>
int each_combination(
char const * source,
char const * mappings[256],
int (*callback)(char const *, void *),
void * thunk
) {
if (mappings == NULL || source == NULL || callback == NULL)
{
return -1;
}
else
{
size_t i;
int rv;
size_t num_mappings[256] = {0};
size_t const source_len = strlen(source);
size_t * const counter = calloc(source_len, sizeof(size_t));
char * const scratch = strdup(source);
if (scratch == NULL || counter == NULL)
{
rv = -1;
goto done;
}
/* cache the number of mappings for each char */
for (i = 0; i < 256; i++)
num_mappings[i] = 1 + (mappings[i] ? strlen(mappings[i]) : 0);
/* pass each combination to the callback */
do {
rv = callback(scratch, thunk);
if (rv != 0) goto done;
/* increment the counter */
for (i = 0; i < source_len; i++)
{
counter[i]++;
if (counter[i] == num_mappings[(unsigned char) source[i]])
{
/* carry to the next position */
counter[i] = 0;
scratch[i] = source[i];
continue;
}
/* use the next mapping for this character */
scratch[i] = mappings[(unsigned char) source[i]][counter[i]-1];
break;
}
} while(i < source_len);
done:
if (scratch) free(scratch);
if (counter) free(counter);
return rv;
}
}
#include <stdio.h>
int print_each(char const * s, void * name)
{
printf("%s:%s\n", (char const *) name, s);
return 0;
}
int main(int argc, char ** argv)
{
char const * mappings[256] = { NULL };
mappings[(unsigned char) 'a'] = "eo";
mappings[(unsigned char) 'b'] = "i";
each_combination("abba", mappings, print_each, (void *) "abba");
each_combination("baobab", mappings, print_each, (void *) "baobab");
return 0;
}
No, non lavoro, aiutare una squadra con una vera vita consegnabile con una scadenza stretta. Sono un ragazzo con doppia E incorporata, che non ha familiarità con le strutture di dati, ecc ... Qualsiasi aiuto sarebbe apprezzato, anche un punto di partenza in una direzione specifica. Stavo pensando in modo ricorsivo, ma non mi sembra giusto. – Gio
@Gio: Ok, qual è la lunghezza massima della mappatura? sono riparati, cioè 2 possibili mappature? come nel tuo esempio sopra? – t0mm13b
Lunghezza massima stringa = 32, numero massimo di mappature = 8, numero massimo di caratteri per mappa = 4. Ovviamente, non viene inserito nella pietra poiché ci sono persone coinvolte nel marketing ... sospiro.Quindi gli indizi sugli algoritmi sarebbero più apprezzati. Possiamo occuparci dei problemi di memoria o di altri ritocchi, se necessario. Verso una riunione. – Gio