Funzione ricorsiva con puntatori

di il
7 risposte

Funzione ricorsiva con puntatori

Ciao a tutti! Avrei bisogno di una mano per risolvere una funzione. In questa funzione devo inserire due insiemi A1 e A2 (utilizzando puntatori, non sapendo la grandezza del vettore che verrà richiesta ed inserita dall'utente) e restituire la loro intersezione(A:1, 2 - B: 1, 2, 3 -= C: 1, 2) creando appunto un nuovo puntatore C. La funzione però deve essere ricorsiva, questo mi mette molto in difficoltà non avendo ben capito questo argomento..
Questo è il codice della funzione che ho scritto:

La parte relativa all'inserimento degli insiemi funziona ed è apposto.
Questo codice mi fa ritornare come risultato:
Inserisci il numero di elementi del primo insieme: 2
Inserisci elemento: 1
Inserisci elemento: 2
Inserisci il numero di elementi dell'insieme che vuoi inserire: 3
Inserisci elemento: 1
Inserisci elemento: 2
Inserisci elemento: 5
L'intersezione dei due insiemi è: 0 0
void intersezione (double a1[], double a2[], int n1, int n2, int count, int i, int j)
{	
	double *c;
	c = (int *) malloc (n1 + n2 * sizeof(int));

	count=0;

	if (n2 >= n1)
	{ 
		if (a1[i] == a2[j])
		{
			c[count] = a1[i];
			count++;
			i++;
			j++;
		
			
		}
		else
		{
			
			intersezione (a1, a2, n1, n2, count, i , j++);
		}
	}
	else
	{
	/*questo pezzo di codice mi fa tornare come risultato "errore di segmentazione", non l'ho ancora guardato bene non sapendo risolvere il problema superiore*/
		if (a2[j] == a1[i])
		{
			c[count] = a2[j];
			count++;
			i++;
			j++;
		
			intersezione (a1, a2, n1, n2, count, i , j);
		}
		else
		{
			i++;
			intersezione (a1, a2, n1, n2, count, i , j);
		}
	}
	printf("L'intersezione dei due insiemi è: ");
		
	for(i = 0; (i <= (count )); i++)
	{
	   printf("%d ",c[count] );
   	}
}
Grazie.
P.S. sono ancora alle prime armi, probabilmente ho sbagliato la maggior parte del codice.

7 Risposte

  • Re: Funzione ricorsiva con puntatori

    Regola: dai alle variabili (e a tutto quello che ha un nome) dei nomi ESPLICATIVI. Non aver paura di battere qualche tasto in più, risparmierai tanti mal di testa!
  • Re: Funzione ricorsiva con puntatori

    nicolap ha scritto:


    Regola: dai alle variabili (e a tutto quello che ha un nome) dei nomi ESPLICATIVI. Non aver paura di battere qualche tasto in più, risparmierai tanti mal di testa!
    Hai ragione scusa, così è più chiaro?

    
    void intersezione (double insieme1[], double insieme2[], int num_elem1, int num_elem2, int count, int i, int j)
    {	
    	double *c;
    	c = (int *) malloc (n1 + n2 * sizeof(int));
    
    	count=0;
    
    	if (num_elem2 >= num_elem1)
    	{ 
    		if (insieme1[i] == insieme2[j])
    		{
    			c[count] = insieme1[i];
    			count++;
    			i++;
    			j++;
    		
    			
    		}
    		else
    		{
    			
    			intersezione (insieme1, insieme2, num_elem1, num_elem2, count, i , j++);
    		}
    	}
    	else
    	{
    	/*questo pezzo di codice mi fa tornare come risultato "errore di segmentazione", non l'ho ancora guardato bene non sapendo risolvere il problema superiore*/
    		if (insieme2[j] == insieme1[i])
    		{
    			c[count] = insieme2[j];
    			count++;
    			i++;
    			j++;
    		
    			intersezione (insieme1, insieme2, num_elem1, num_elem2, count, i , j);
    		}
    		else
    		{
    			i++;
    			intersezione (insieme1, insieme2, num_elem1, num_elem2, count, i , j);
    		}
    	}
    	printf("L'intersezione dei due insiemi è: ");
    		
    	for(i = 0; (i <= (count )); i++)
    	{
    	   printf("%d ",c[count] );
       	}
    }
    
  • Re: Funzione ricorsiva con puntatori

    Ciao.

    Innanzitutto non basta mostrare la funzione ricorsiva, ma devi anche mostrare come avvii la ricorsione nel main.

    La malloc sicuramente deve essere fatta una volta sola e deve essere della size del minimo tra la dimensione dei due insiemi; inoltre deve essere coerente con il tipo degli insiemi: a parte che la formula è sbagliata, comunque se gli array sono double ci deve essere un sizeof(double).

    Poi non si è capito bene: ma l'allocazione dell'array con la soluzione deve essere dentro o fuori il meccanismo di ricorsione? Perché da come hai enunciato il problema sembrerebbe dentro, ma da come hai scritto la soluzione no (non c'è scambio di puntatore tra un passaggio e l'altro)
  • Re: Funzione ricorsiva con puntatori

    Weierstrass ha scritto:


    Ciao.

    Innanzitutto non basta mostrare la funzione ricorsiva, ma devi anche mostrare come avvii la ricorsione nel main.

    La malloc sicuramente deve essere fatta una volta sola e deve essere della size del minimo tra la dimensione dei due insiemi; inoltre deve essere coerente con il tipo degli insiemi: a parte che la formula è sbagliata, comunque se gli array sono double ci deve essere un sizeof(double).

    Poi non si è capito bene: ma l'allocazione dell'array con la soluzione deve essere dentro o fuori il meccanismo di ricorsione? Perché da come hai enunciato il problema sembrerebbe dentro, ma da come hai scritto la soluzione no (non c'è scambio di puntatore tra un passaggio e l'altro)
    Ciao, scusa quindi cosa devo fare?
    Quale sarebbe la formula della malloc, se non è questa?
  • Re: Funzione ricorsiva con puntatori

    Sapresti spiegarci a parole quale sarebbe la tua idea per trovare l'intersezione tra due array? La ricorsione in cosa dovrebbe consistere in questo caso?

    In ogni caso il mio consiglio è quello di iniziare a risolvere il problema in modo iterativo e a quel punto potremo ragionare su come convertire l'algoritmo sfruttando la ricorsione.
  • Re: Funzione ricorsiva con puntatori

    Nippolo ha scritto:


    Sapresti spiegarci a parole quale sarebbe la tua idea per trovare l'intersezione tra due array? La ricorsione in cosa dovrebbe consistere in questo caso?

    In ogni caso il mio consiglio è quello di iniziare a risolvere il problema in modo iterativo e a quel punto potremo ragionare su come convertire l'algoritmo sfruttando la ricorsione.
    Ecco ho provato ha riscrivere la funzione iterativa, ho controllato tutti i passaggi, mi sembrano giusti. L'unico problema è che l'array non prende in dato il vettore che gli passo.
    Il count, funziona.
    double intersezione (double a1[], double a2[], int n1, int n2, int count, int i, int j)
    {	
    	double c[n1+n2];
    	
    
    
    	count=0;
    	j = 0;
     
    	if (n2 >= n1)
    	{ 
    	for(i=0; i< n1;)
    	{
    		if (a1[i] == a2[j])
    		{
    			c[count] = a1[i];
    			count++;
    			i++;
    			j = 0;
    		
    			
    		}
    		else
    		{
    			j++;
    			if(j >= n2)
    			{ 
    			   i++;
    			   j=0;
    			}
    			
    		}
    	}}
    	else if (n1 > n2)
    	{
    	for(i=0; i< n2;)
    	{
    
    		if (a2[i] == a1[j])
    		{
    			c[count] = a2[i];
    			count++;
    			i++;
    			j = 0;
    		
    			
    		}
    		else
    		{
    			j++;
    			if(j >= n1)
    			{ 
    			   i++;
    			   j=0;
    			}
    			
    		}
    	}}
    
    		printf("\nCOUNT: %d\n\n", count);
    	
    	if (count != 0)
    	{	
    	printf("L'intersezione dei due insiemi è: ");
    
    		for(i = 0; (i <= (count -1 )); i++)
    		{
    	 	  printf("%d ",c[i] );				/*mi esce sempre 0 */
       		}
    	}
    	else
    	{
    		printf("Non esiste intersezione \n");
    	}
    }
    
  • Re: Funzione ricorsiva con puntatori

    Allora:
    - stando al prototipo della funzione mi aspetterei che venga ritornato un double;
    - i parametri i, j e count non hanno senso di esistere, in quanto non determinano nessuno scambio di informazioni tra il main e la funzione e viceversa;
    - perchè lavorare con dei double e non semplicemente con delle variabili intere?
    - perchè complicarsi la vita considerando separatamente i casi in cui n2>=n1 e n1>n2, quando basta semplicemente scorrere a2 per ogni singolo elemento di a1 ricorrendo a due cicli for innestati?!
    - ti faccio inoltre notare che non stai considerando l'eventualità che gli array possano contenere elementi che si ripetono. Per esempio per gli array (2 5 2) e (7 2 2) il tuo codice dovrebbe ritornare come intersezione (2 2) e non il risultato che sarebbe lecito aspettarsi, ossia (2).

    EDIT/P.S.
    Lo specificatore di formato per i double è %lf e non %d
Devi accedere o registrarti per scrivere nel forum
7 risposte