Permutazioni possibili di n numeri

di il
2 risposte

Permutazioni possibili di n numeri

Ciao a tutti
questo è il mio primo post. sono alcuni mesi che da autodidatta mi sto riacculturando sul linguaggio c, da me studiato ai tempi delle superiori. come ambiente di sviluppo uso xcode 3.0, in quanto ho un mac con sistema operativo mac os 10.5.8.
mi sono posto il problema di creare una matrice in cui stampare tutte le possibili permutazioni di n numeri, caricati su un vettore.
il codice essenziale, tralasciando quello ovvio, è questo:
dal main:

do
{
printf("\ngli elementi devono essere tutti diversi\n");

for(i = 0; i < numero; i++)
{
printf("numero %d: ", i + 1);
scanf("\n%d", &v_ini);
}
//se ritorna 0 il ciclo si ripete
}while(!(elem_uguali(v_ini, numero)));

if(numero > 3)
{
for(i = 0; i < numero - 2; i++)
{
a = i + 1;
for(j = a; j < numero - 1; j++)
{
b = j + 1;
for(k = b; k < numero; k++)
{
v_due[0] = v_ini;
v_due[1] = v_ini[j];
v_due[2] = v_ini[k];

riga = scambio_a_tre(crea_vett(v_due, v_ini, numero), riga, numero);
}
}
}
}

//****************************************************************************
int *crea_vett(int *v_secondo, int *v_inizio, int lato)
{
int iii, *v_scrivere, jjj = 3;
v_scrivere = (int*)malloc(lato * sizeof(int));

for(iii = 0; iii < lato; iii++) v_scrivere[iii] = v_secondo[iii];

iii = 0;
while(jjj < lato)
{
if(!(trova_elem(v_inizio[iii], v_secondo, lato)))
{
v_scrivere[jjj] = v_inizio[iii];
jjj++;
iii++;
}
else iii++;
}
return v_scrivere;
}

//************************************************************************
int scambio_a_tre(int *vett, int riga, int lato) //lato = numero
{
int var_scambio, scambi, iii, jj = 1;

for(iii = 0; iii < lato; iii++) M[riga][iii] = vett[iii];
riga++;
for(scambi = 0; scambi < 5; scambi++) //effettua 5 scambi
{
for(iii = 0; iii < lato; iii++) M[riga][iii] = M[riga - 1][iii];
var_scambio = M[riga][jj];
M[riga][jj] = M[riga][jj - 1];
M[riga++][jj - 1] = var_scambio;

if(++jj == 3) jj = 1;
}
return riga; //torna la prossima riga
}

//**********************************************************************************
int trova_elem(int trova, int *vettore, int lato)
{
if(lato < 0) return 0;
if(vettore[lato - 1] == trova) return 1;
else return trova_elem(trova, vettore, lato - 1);
}

non capisco perchè la riga:
v_scrivere[jjj] = v_inizio[iii];
mi da dei risultati anomali. nel vettore v_inizio ci sono caricati i numeri forniti dall'utente.
vi stampo anche la videata di risultato:
1 2 3 287609381
2 1 3 287609381
2 3 1 287609381
3 2 1 287609381
3 1 2 287609381
1 3 2 287609381
1 2 4 3
2 1 4 3
2 4 1 3
4 2 1 3
4 1 2 3
1 4 2 3
1 3 4 2
3 1 4 2
3 4 1 2
4 3 1 2
4 1 3 2
1 4 3 2
2 3 4 1
3 2 4 1
3 4 2 1
4 3 2 1
4 2 3 1
2 4 3 1

perchè nelle prime 6 combinaizioni mi scrive il numero 287609381?
poi sembra che anche l'istruzione printf, messa da me per analizzare l'andamento del programma, cambi il risultato. com'è possibile?
se qualcuno mi sa aiutare lo ringrazierei molto,
ciao
Andrea

p.s. spero di aver rispettato il regolamento del forum, se non l'ho fatto me ne dispiace molto. scusate.

2 Risposte

  • Re: Permutazioni possibili di n numeri

    MODIFICA il tuo primo post e inserisci il codice (formattato) nei tag "code":

    [ code ]
    ...

    [ /code ]

    Se no, non si capisce nulla.

    Il numero strano e' dovuto ad un elemento del vettore che stampi in uscita, non inizializzato.

    Ogni volta che crei una variabile, o allochi un'area di memoria, inizializzala!

    Ad esempio, invece di malloc(size), usa calloc(1,size), che fa la stessa cosa, ma inizializza il blocco di memoria a 0!
  • Re: Permutazioni possibili di n numeri

    Dunque il codice completo è questo
    
    //raggruppare il numero in gruppetti da 3, poi fare le possibili variazioni
    #include <stdio.h>
    #include <stdlib.h>
    
    int numero, i, j, k, a, b, n_righe, **M, *v_ini, *v_due, ii, riga = 0;
    
    int *crea_vett(int *v_secondo, int *v_inizio, int lato);
    
    int main(void)
    {
    	printf("\nnumero: ");
    	scanf("\n%d", &numero);
    
    	n_righe = fatt(numero); 
    
    	M = (int**)malloc(n_righe * sizeof(int*));
    	for(i = 0; i < n_righe; i++) 
    		M[i] = (int*)malloc(numero * sizeof(int));	
    	
    	v_ini = (int*)malloc(numero * sizeof(int));
    	v_due = (int*)malloc(numero * sizeof(int));
    
    	do
    	{
    		printf("\ngli elementi devono essere tutti diversi\n");
    		
    		for(i = 0; i < numero; i++)
    		{
    			printf("numero %d: ", i + 1);
    			scanf("\n%d", &v_ini[i]);
    		}
    			//se ritorna 0 il ciclo si ripete
    	}while(!(elem_uguali(v_ini, numero))); 
    	
    	if(numero > 3)
    	{
    		for(i = 0; i < numero - 2; i++)
    		{
    			a = i + 1;
    			
    			for(j = a; j < numero - 1; j++)
    			{
    				b = j + 1;
    				
    				for(k = b; k < numero; k++)
    				{
    					v_due[0] = v_ini[i];
    					v_due[1] = v_ini[j];
    					v_due[2] = v_ini[k];
    				
    					riga = scambio_a_tre(crea_vett(v_due, v_ini, numero), riga, numero);
    				}
    			}
    		}
    	}
    	else if(numero == 3)
    		scambio_a_tre(v_ini, 0, numero);	
    	
    	if(confronto(M, n_righe - 1, numero))
    	{
    		printf("\ni vettori risultanti sono tutti diversi");
    		getchar();
    		for(j = 0; j < n_righe; j++)
    		{
    			printf("\n");
    			for(i = 0; i < numero; i++) printf("%d ", M[j][i]);
    		}	
    	}
    	else printf("\nci sono vettori uguali");
    
    return 0;
    }
    //****************************************************************************
    int *crea_vett(int *v_secondo, int *v_inizio, int lato)
    {
    	int iii, *v_scrivere, jjj = 3;
    	
    	v_scrivere = (int*)malloc(lato * sizeof(int));
    
    	for(iii = 0; iii < lato; iii++) v_scrivere[iii] = v_secondo[iii]; 
    
    	iii = 0;
    	while(jjj < lato)
    	{
    		if(!(trova_elem(v_inizio[iii], v_secondo, lato)))
    		{
    			v_scrivere[jjj] = v_inizio[iii];
    			jjj++; 
    			iii++;
    		}
    		else iii++;
    	}
    	return v_scrivere;
    }
    
    
    //************************************************************************
    int scambio_a_tre(int *vett, int riga, int lato)  //lato = numero
    {
    	int var_scambio, scambi, iii, jj = 1;
    
    	for(iii = 0; iii < lato; iii++) M[riga][iii] = vett[iii];
    	
    	riga++;
    	
    	for(scambi = 0; scambi < 5; scambi++)			//effettua 5 scambi
    	{
    		for(iii = 0; iii < lato; iii++) M[riga][iii] = M[riga - 1][iii];
    		 
    		var_scambio = M[riga][jj];
    		M[riga][jj] = M[riga][jj - 1];
    		M[riga++][jj - 1] = var_scambio;
    		
    		if(++jj == 3) jj = 1;
    	}	
    	return riga;		//torna la prossima riga
    }
    
    //**********************************************************************************
    int trova_elem(int trova, int *vettore, int lato)
    {
    	if(lato < 0) return 0;
    	
    	if(vettore[lato - 1] == trova) return 1;
    	else return trova_elem(trova, vettore, lato - 1);
    }
    
    //***************************************************************************
    int confronto(int **matr, int cont, int lato)
    {
    	int ii, jj, c;
    
    	if(cont == 0) return 1;	//ritorna 1 se vett è diverso da tutti gli altri vettori
    
    	for(jj = 0; jj < cont; jj++)	
    	{	
    		c = 0;
    		for(ii = 0; ii < lato; ii++) 
    			if(matr[cont][ii] == matr[jj][ii]) c++;
    		if(c == lato) return 0;
    	}
    	
    	return confronto(matr, cont - 1, lato);
    }
    
    //**************************************************************************
    int elem_uguali(int *vettore, int n)
    {
    	int ii;
    	
    	if(n == 0) return 1;
    	
    	for(ii = 0; ii < n; ii++)
    		if(vettore[n] == vettore[ii]) return 0;
    			
    	return elem_uguali(vettore, n - 1);
    }
    
    //**************************************************************************
    int fatt(int var)
    {
    	if(var == 0) return 1;
    	else return var * fatt(var - 1);
    }
    
    
    spero di essere riuscito a inserirlo in modo corretto e chiaro, scusa ieri era il mio primo post e non sapevo di questa possibilità.
    cmq non comprendo perchè il vettore v_inizio, all'interno della funzione mi assume quei valori, anche perchè li contiene semplicemente i valori inseriti dall'utente.
    poi se inserisco
    printf("\n %d", v_inizio[iii]); getchar(); prima dell'istruzione
    if(!(trova_elem(v_inizio[iii], v_secondo, lato)))

    per controllare il variare della variabile v_inizio il programma mi da esito diverso
    e questo è quello che appare sulla
    1
    2
    3
    4
    1
    2
    3
    0
    1
    2
    3
    0
    0
    0
    0
    questo semplicemente per un printf();

    tu mi dici di usare calloc(), ma come posso la malloc con la calloc()
    grazie per l'aiuto!
Devi accedere o registrarti per scrivere nel forum
2 risposte