[C] Ricorsione esercizio C su vettore

floppyes
Ciao a tutti!

Ho un problema con questa funzione ricorsiva, non riesco a capire come mai non funziona correttamente.

Testo:
Scrivere una funzione ricorsiva (in C) che, avendo in input un array di n interi di interi positivi, dia in output TRUE se tutti gli elementi sono maggiori di 10, FALSE altrimenti.

Mia soluzione:
int magg_dieci (int a[], int n)
{
   if (n==0)
      return  1;
   else
      if (a[n] > 10 )
         return 1;
   else
      return
      magg_dieci(a, n-1);
}


Io dico che se n==0 allora mi ritorna 1, perché non ho valori all'interno del mio vettore, se l'elemento di a[n] è maggiore di 10 allora mi ritorna 1, altrimenti mi ritorna la mia funzione.

Se provo a mettere tutto nel main principale ottengo però che la funzione non sempre mi da il risultato corretto.

#include <stdio.h>
#define TRUE 1
#define FALSE 0

int magg_dieci (int a[], int n)
{
   if (n==0)
      return  0;
   else
      if (a[n] > 10 )
         return 1;
   else
      return
      magg_dieci(a, n-1);
}

int main ()
{
   int seq[]={454,33,2}, tot=3;
   printf("%d ", magg_dieci(seq,tot));
   return 0;
}


Sapete indicarmi come posso modificarla?

Grazie
Ciaoo :)

Risposte
apatriarca
La tua logica è al contrario. Tu puoi uscire dalla funzione ricorsiva solo se incontri un elemento che NON è maggiore di 10. In questo caso infatti puoi dire che non è vero che tutti gli elementi sono maggiori di 10 perché ne hai trovato uno che non rispetta la condizione. Se trovi un elemento maggiore di 10 non puoi dire invece nulla. Per cui la logica dovrebbe essere:

if (n <= 0) { return 1; }
else if (a[n-1] <= 10) { return 0; }
else { return magg_dieci(a, n-1); }


Nota che ho anche corretto l'uso dell'indice \(n\). Se la dimensione è \(n\), allora gli indici dell'array vanno da \(0\) a \(n-1\)..

floppyes
Ciao!

Perfetto grazie mille. Con queste funzioni ricorsive non riesco mai a scrivere correttamente il codice! Ad esempio ho un altro esercizio in cui mi viene chiesto di scrivere una funzione ricorsiva che inverta l'ordine delle parole in un array.

Non riesco a capire come scrivere il codice. Con una funzione normale andrei a stampare il vettore con un ciclo for, partendo dall'ultimo valore e tornando indietro:
for (i=DIM-1;i>=0;i--)
{
   printf("%c", v[DIM]);
}


Non riesco però a ricavarmi il codice per la funzione ricorsiva.

Grazie
Ciaoo :)

apatriarca
L'idea è quella di fare la chiamata ricorsiva che stampa il resto della stringa al contrario e stampare quindi il valore corrente.

floppyes
Ciao!

Ho provato a scrivere questa funzione ma non va ancora

int stampa(char v[], int n)
{
   if (n==0)
      return 0;
   else
      printf("%c", v[n]);
   return inverti (v,n-1);
}


Ma non viene eseguita.

Grazie
Ciaoo :)

apatriarca
No, devi PRIMA fare la chiamata ricorsiva e POI stampare il carattere corrente.
void inverti(char *str, int n)
{
    if (n <= 0) { return; }

    inverti(str+1, n-1);
    putchar(*str);
}

floppyes
Ciao!

Perfetto grazie mille. Adesso inizia ad essermi più chiaro! Ho provato a fare un'altro esercizio, trovare il numero più grande in un vettore. Può andare bene?
int massimo (int v[], int n)
{
   if (n > 0)
   {
      if (v[n] > massimo(v, n-1))
         return v[n];
      else
         return  massimo(v, n-1);
   }
   else
      return v[n];
}


Funzionare funziona, ho provato e mi ritorna sempre il massimo, più che altro volevo sapere se come "logica" è corretta :)

Grazie
Ciaoo :)

apatriarca
Come ti ho già scritto, se un vettore ha \(n\) elementi allora gli indici vanno da \(0\) a \(n-1\). Il tuo codice è quindi sbagliato. Dovrebbe essere:
int massimo (int v[], int n)
{
   if (n <= 0) { /* gestisci l'errore in qualche modo.. */  }
   if (n == 1) { return v[0]; }

   int max_resto = massimo(v, n-1);
   return v[n-1] > max_resto ? v[n-1] : max_resto;
}

floppyes
Ciao!

Grazie per la risposta. Quindi devo prima gestire i vari casi, poi passare sempre l'indice n-1.

Seguendo questo ragionamento allora posso fare una funzione ricorsiva anche per il calcolo del minimo:
int minimo (int v[], int n)
{
	if (n<=0)
		return -1;
	if (n==1)
		return v[0];

	int min=minimo(v,n-1);
	if (v[n-1] < min)
		return v[n-1];
	else
		return min;
}


Un'ultima domanda! Se io voglio trovare sempre con una funzione ricorsiva, il massimo numero pari presente in un vettore, mi basta solamente aggiungere la condizione: v[n-1]%2==0 nell'if finale giusto?
int massimo (int v[], int n)
{
   if (n <= 0)
      return -1;
   if (n == 1)
      return v[0];

   int max_resto = massimo(v, n-1);

   if (v[n-1]>max_resto && v[n-1]%2==0)
      return v[n-1];
   else
      return max_resto;
}


Grazie mille per l'aiuto
Ciaoo :)

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.