Permutations

Standard

Descrizione

Genera tutte le possibili combinazioni di lunghezza N con K caratteri diversi.


Sorgente

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
   int len_counters;
   int *counters;

   int len_symbols;
   char *list_symbols;
} PermutationData;

typedef enum { false = 0, true } bool;

void set_perm_cnt (PermutationData *pdata, int permutation)
{
 pdata->len_counters = permutation;
 pdata->counters = (int *) calloc (permutation, sizeof (int));
}

void make_list_symbols (PermutationData *pdata, bool flag_digit, bool flag_alpha,
                        bool flag_case, bool flag_extra, char *extra)
{
 int j = 0, k;
 char *extra_symbols = "_-.,";

 pdata->len_symbols = (flag_digit ? '9' - '0' : 0)
                    + (flag_alpha ? 'z' - 'a' : 0)
                    + (flag_case  ? 'Z' - 'A' : 0) + 1;
 if ( flag_extra )
      pdata->len_symbols += strlen (extra);
 else pdata->len_symbols += 4;

 pdata->list_symbols = (char *) malloc (pdata->len_symbols * sizeof (char));

 if ( flag_digit )
      for ( k = '0'; k <= '9'; k++, j++ )
            pdata->list_symbols[j] = k;

 if ( flag_alpha )
      for ( k = 'a'; k <= 'z'; k++, j++ )
            pdata->list_symbols[j] = k;

 if ( flag_case )
      for ( k = 'A'; k <= 'Z'; k++, j++ )
            pdata->list_symbols[j] = k;

 if ( flag_extra ) {
	  if ( flag_extra )
	       extra_symbols = extra;

	  for ( k = strlen (extra_symbols); k > -1; k--, j++ )
	        pdata->list_symbols[j] = extra_symbols[k];
 }

 pdata->list_symbols[j] = '\0';
 pdata->len_symbols = strlen (pdata->list_symbols);
}

bool do_permutation (PermutationData *pdata)
{
 int j;
 bool report;

 for ( j = 0; j < pdata->len_counters; j++ )
       putchar (pdata->list_symbols[pdata->counters[j]]);
 putchar ('\n');

 for ( j = 0, report = false; j < pdata->len_counters; j++ ) {
	   if ( !j || report ) {
		    pdata->counters[j]++;
		    report = false;

		    if ( pdata->counters[j] >= pdata->len_symbols ) {
				 pdata->counters[j] = 0;
				 report = true;
				 continue;
		    }
	   }
 }

 return !report;
}

int main (int argc, char *argv[])
{
 PermutationData pdata;

 if ( argc < 2 ) {
	  printf ("Usage: %s len_string\n", *argv);
	  return 1;
 }

 set_perm_cnt (&pdata, atoi (argv[1]));
 make_list_symbols (&pdata, true, true, true, false, NULL);

 while ( do_permutation (&pdata) );

 free (pdata.list_symbols);
 free (pdata.counters);

 return 0;
}