Funzione ricorsiva con puntatori

di Anonimizzato26181 il
7 risposte
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

  • 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!
  • 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] );
       	}
    }
    
  • 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)
  • 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?
  • 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.
  • 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");
    	}
    }
    
  • 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