[C] Max intero dispari funzione ricorsiva
Ciao a tutti!
Non riesco a trovare dov'è l'errore in questo esercizio:
Scrivere una funzione ricorsiva C che produca il massimo intero dispari in una dato vettore di n variabili intere (0 se il vettore non contiene interi dispari)
Prima ho provato a scrivere il codice senza utilizzare la funzione ricorsiva e funziona tutto quanto (al posto di usare n variabili ho definito n=5)
Ho provato poi a riscrivere il programma creando l'apposita funzione, però continua a darmi come numero massimo lo zero!
Grazie mille
Buon fine settimana
Ciaoo
Non riesco a trovare dov'è l'errore in questo esercizio:
Scrivere una funzione ricorsiva C che produca il massimo intero dispari in una dato vettore di n variabili intere (0 se il vettore non contiene interi dispari)
Prima ho provato a scrivere il codice senza utilizzare la funzione ricorsiva e funziona tutto quanto (al posto di usare n variabili ho definito n=5)
/* Esercizio 6. Scrivere una funzione ricorsiva C che produca il massimo intero dispari in una dato vettore di n variabili intere (0 se il vettore non contiene interi dispari) FacSimileSezione1. */ #include <stdio.h> #define dim1 5 int main () { int num, i, vett[dim1], vettdisp[dim1], flag=0, max=0; for (i=0;i<dim1;i++) { printf("Inserisci il %d° numero: ", i+1); scanf("%d", &num); if (num%2!=0) { vett[i]=num; } } printf("\nNumeri dispari inseriti: "); for (i=0;i<dim1;i++) { printf("%2d", vett[i]); } for (i=0;i<dim1;i++) { if(vett[i]!=0) { max=vett[i]; break; } } for (i=0;i<dim1;i++) { if (vett[i+1]>max && vett[i+1]!=0) { max=vett[i+1]; } } printf("\n\nIl massimo numero dispari: %d", max); return 0; }
Ho provato poi a riscrivere il programma creando l'apposita funzione, però continua a darmi come numero massimo lo zero!
/* Esercizio 6. Scrivere una funzione ricorsiva C che produca il massimo intero dispari in una dato vettore di n variabili intere (0 se il vettore non contiene interi dispari) FacSimileSezione1. */ #include <stdio.h> #define dim1 5 void maxdisp (int vett[]); int main () { int num, i, vett[dim1], max; for (i=0;i<dim1;i++) { printf("Inserisci il %d° numero: ", i+1); scanf("%d", &num); if (num%2!=0) { vett[i]=num; } } printf("\nNumeri dispari inseriti: "); for (i=0;i<dim1;i++) { printf("%2d", vett[i]); } maxdisp (vett); printf("\n\nIl massimo numero dispari: %d", max); return 0; } void maxdisp (int vett[]) { int i; int max=0; for (i=0;i<dim1;i++) { if(vett[i]!=0) { max=vett[i]; break; } } for (i=0;i<dim1;i++) { if (vett[i+1]>max && vett[i+1]!=0) { max=vett[i+1]; } } }
Grazie mille
Buon fine settimana
Ciaoo

Risposte
Come mai la funzione ha un for al suo interno?
La funzione dovrebbe essere definita come:
\(\displaystyle f(v,n) = \begin{cases} f(v,n-1) &\text{ se } v_n \text{ è pari } \\ \max(v_n, f(v,n-1)) &\text{ se } v_n \text{ è dispari } \\ 0 &\text{ se } n=0 \end{cases} \)
Nel codice C puoi anche togliere il primo elemento invece che l'ultimo, ma in formule era più semplice così.
La funzione dovrebbe essere definita come:
\(\displaystyle f(v,n) = \begin{cases} f(v,n-1) &\text{ se } v_n \text{ è pari } \\ \max(v_n, f(v,n-1)) &\text{ se } v_n \text{ è dispari } \\ 0 &\text{ se } n=0 \end{cases} \)
Nel codice C puoi anche togliere il primo elemento invece che l'ultimo, ma in formule era più semplice così.
Questa dovrebbe fare qualcosa di simile a ciò che richiedi, ma prendi tutto con le pinze

#include <stdio.h> #include <stdlib.h> #define N 5 int max(int *vett,int n); int main() { int vett[N],i; for(i=0;i<N;i++) { printf("Inserisci l'elemento %d: ",i+1); scanf("%d",&vett[i]); } printf("Ecco il massimo: %d",max(vett,N)); return 0; } int max(int *vett, int n) { int maxdisp; if (n==1&&vett[0]%2!=0) return vett[0]; if (n==2&&vett[0]%2!=0) { if((vett[0]>vett[1])&&(vett[0]%2!=0)) return vett[0]; else return vett[1]; } maxdisp = max(&vett[1],n-1); if ((vett[0]>maxdisp)&&(vett[0]%2!=0)) return vett[0]; else if(maxdisp%2!=0) return maxdisp; return 0; }
C'è un errore nell'inserimento dei valori dispari del vettore:
Se il numero i-esimo inserito dall'utente è un valore pari, tu salti la posizione i, e dunque in vettore ci sarà un valore random. Devi usare un'altra variabile per la creazione del vettore.
Penso che l'esercizio chiedesse di fare quello che ha fatto Obidream, ma se lo volessimo fare come hai fatto tu, e cioè prima isoli i numeri dispari e poi calcoli il massimo fra di essi (il risultato chiaramente è lo stesso ma il codice diventa molto più semplice), allora la correzione di quello che hai scritto sarebbe questa:
"floppyes":
Ciao a tutti!
for (i=0;i<dim1;i++) { printf("Inserisci il %d° numero: ", i+1); scanf("%d", &num); if (num%2!=0) { vett[i]=num; } }
Se il numero i-esimo inserito dall'utente è un valore pari, tu salti la posizione i, e dunque in vettore ci sarà un valore random. Devi usare un'altra variabile per la creazione del vettore.
Penso che l'esercizio chiedesse di fare quello che ha fatto Obidream, ma se lo volessimo fare come hai fatto tu, e cioè prima isoli i numeri dispari e poi calcoli il massimo fra di essi (il risultato chiaramente è lo stesso ma il codice diventa molto più semplice), allora la correzione di quello che hai scritto sarebbe questa:
#include <stdio.h> #define dim1 5 int maxdisp (int vett[], int j); //funzione di tipo int int main () { int num, i, vett[dim1], max; int j=0; for (i=0;i<dim1;i++) { printf("Inserisci il %d° numero: ", i+1); scanf("%d", &num); if (num%2!=0) { vett[j]=num; ++j; } } printf("\nNumeri dispari inseriti: \n"); for (i=0;i<j;i++) { printf("%d \n", vett[i]); } max= maxdisp (vett,j-1); //questa e' una funzione che ritorna un valore printf("\n\nIl massimo numero dispari e': %d", max); return 0; } int maxdisp (int vett[], int j) //funzione di tipo int { if (j==0) return vett[0]; if (j>0) { if (vett[j]> maxdisp(vett,j-1)) return vett[j]; else return maxdisp(vett, j-1); } }
Ciao a tutti!
Scusate per il ritardo ma ho una connessione che va sempre più lenta
Il codice di Obidream funziona alla perfezione, ma ad esser sincero non sarei mai stato in grado di scrivere una funzione del genere. Non ho ancora capito bene infatti la parte finale.
Perchè ad esempio utilizzi la variabile n?
Non ho capito bene che passaggi fa il programma per trovare il massimo.
Guardando invece il codice di Atem ho capito l'errore, io continuavo ad utilizzare un vettore i, invece dovevo utilizzare un altro vettore j per salvare solamente i dispari. Però non mi sono chiari questi due passaggi:
I primi due if servono a verificare se ci sono dei numeri dispari, ma questo pezzo di funzione cosa fa esattamente?
Inoltre quando lo compilo ottengo questo errore:
Allora ho aggiunto all'interno della funzione di tipo int un return 0; prima dell'ultima parentesi, va bene oppure deve mostrare un altro valore?
Infine riga 26 e 27, scrivere:
in questo modo:
è la stessa cosa giusto?
Ultima domanda: leggendo sul libro la definizione di ricorsione: "una funzione può chiamare se stessa, in maniera diretta o indiretta". Quindi se mi chiedono di realizzare una funzione ricorsiva devo sempre creare un main che richiama una funzione, come in questo esercizio giusto?
Grazie mille
Ciaoo
Scusate per il ritardo ma ho una connessione che va sempre più lenta

Il codice di Obidream funziona alla perfezione, ma ad esser sincero non sarei mai stato in grado di scrivere una funzione del genere. Non ho ancora capito bene infatti la parte finale.
Perchè ad esempio utilizzi la variabile n?

if (n==1&&vett[0]%2!=0) return vett[0]; if (n==2&&vett[0]%2!=0)
Non ho capito bene che passaggi fa il programma per trovare il massimo.
Guardando invece il codice di Atem ho capito l'errore, io continuavo ad utilizzare un vettore i, invece dovevo utilizzare un altro vettore j per salvare solamente i dispari. Però non mi sono chiari questi due passaggi:
if (vett[j]> maxdisp(vett,j-1)) return vett[j]; else return maxdisp(vett, j-1);
I primi due if servono a verificare se ci sono dei numeri dispari, ma questo pezzo di funzione cosa fa esattamente?
Inoltre quando lo compilo ottengo questo errore:
Untitled 3.c:43:1: warning: control may reach end of non-void function [-Wreturn-type] } ^ 1 warning generated.
Allora ho aggiunto all'interno della funzione di tipo int un return 0; prima dell'ultima parentesi, va bene oppure deve mostrare un altro valore?
Infine riga 26 e 27, scrivere:
max= maxdisp (vett,j-1); //questa e' una funzione che ritorna un valore printf("\n\nIl massimo numero dispari e': %d", max);
in questo modo:
printf("\n\nIl massimo numero dispari e': %d", maxdisp (vett,j-1));
è la stessa cosa giusto?
Ultima domanda: leggendo sul libro la definizione di ricorsione: "una funzione può chiamare se stessa, in maniera diretta o indiretta". Quindi se mi chiedono di realizzare una funzione ricorsiva devo sempre creare un main che richiama una funzione, come in questo esercizio giusto?
Grazie mille
Ciaoo

Una funzione si dice ricorsiva quando all'interno della propria definizione compare una chiamata direttamente alla funzione stessa.
Questa forma di ricorsione si chiama ricorsione diretta.
Si parla invece di ricorsione indiretta quando nella definizione di una funzione compare la chiamata ad un'altra funzione la quale direttamente o indirettamente chiama la funzione iniziale.
Utilizzo sempre la variabile n per escludere i due casi banali del problema, ovvero i casi in cui il vettore può contenere uno o due elementi
Questa forma di ricorsione si chiama ricorsione diretta.
Si parla invece di ricorsione indiretta quando nella definizione di una funzione compare la chiamata ad un'altra funzione la quale direttamente o indirettamente chiama la funzione iniziale.
Utilizzo sempre la variabile n per escludere i due casi banali del problema, ovvero i casi in cui il vettore può contenere uno o due elementi

"floppyes":
Untitled 3.c:43:1: warning: control may reach end of non-void function [-Wreturn-type] } ^ 1 warning generated.
Allora ho aggiunto all'interno della funzione di tipo int un return 0; prima dell'ultima parentesi, va bene oppure deve mostrare un altro valore?
E' un warning, non un errore.
Quel warning mette in luce il punto debole di questo codice, e cioè se gli passi un vettore vuoto ti ritorna un valore completamente casuale. Se quel warning ti da fastidio puoi eliminarlo scrivendo questo codice:
int maxdisp (int vett[], int j) //funzione di tipo int { if (j>0) { if (vett[j]> maxdisp(vett,j-1)) return vett[j]; else return maxdisp(vett, j-1); } return vett[0]; }
E non ti verrà fuori il warning in quanto c'è un return con valore prima dell'ultima graffa ma anche così, ma sebbene non ci sia nessun warning il punto debole evidenziato in precedenza permane, o meglio in questo caso se gli passi un vettore vuoto non ti restituirà un valore completamente random ma quello che c'è dentro vett[0] che comunque non conosci visto che il vettore era vuoto.
Questo "punto debole" lo puoi eliminare in 2 modi:
a)controllando nel MAIN, prima di chiamare la funzione, che il vettore dei numeri dispari non sia vuoto, e cioè che j>0
b)come hai detto tu, mettendo un valore predefinito nell'ultimo return, cioè lasciare il codice che ti avevo scritto ieri e scrivere alla fine return 0;
in quest'ultimo caso, dopo la chiamata della funzione dovrai controllare che il valore restituito dalla funzione sia diverso da 0, perchè se è 0 vuol dire che il vettore era vuoto, ma fra i due metodi è ovviamente preferibile usare il metodo a) e se proprio ti da fastidio quel warning puoi scrivere la funzione ricorsiva come l'ho scritta ora.
Chiaramente se fai come hai detto tu e cioè se metti un return 0 alla fine della funzione devi usare b) altrimenti quello 0 che sarebbe un messaggio d'errore sarebbe completamente superfluo.
Ciao!
Grazie per la risposta. Ho provato a riscrivere il mio codice che non funzionava così:
Secondo te può andare bene? Funzionare ho visto che funziona, la ricorsione l'ho inserita e restituisce zero in caso non ci siano interi dispari.
Grazie
Ciaoo!
Grazie per la risposta. Ho provato a riscrivere il mio codice che non funzionava così:
/* Programma che mi mostra il massimo numero dispari inserito. Per farlo utilizzo una funzione apposita che viene poi richiamata all'interno del primo main */ #include <stdio.h> #define dim 5 // Prototipo della funzione int massimo (int vett[dim], int j); // Main pri int main (void) { int vett[dim]; int i, num, j; for (i=0;i<dim;i++) { printf("Inserisci il %d° numeri: ", i+1); scanf("%d", &num); if (num!=0 && num%2!=0) { vett[j]=num; j++; } } printf("\nIl numero massimo vale: %d", massimo(vett,j)); return 0; } int massimo (int vett[dim], int j) { int max; int i; if (j==0) { return vett[0]; } while (vett[i]!=0 && vett[i]%2!=0) { max=vett[i]; i++; } for (i=0;i<dim;i++) { if (vett[i]>max && vett[i]!=0 && vett[i]%2!=0) { max=vett[i]; } } return max; }
Secondo te può andare bene? Funzionare ho visto che funziona, la ricorsione l'ho inserita e restituisce zero in caso non ci siano interi dispari.
Grazie
Ciaoo!
"floppyes":
I primi due if servono a verificare se ci sono dei numeri dispari, ma questo pezzo di funzione cosa fa esattamente?
No, i primi due "if" non servono assolutamente a verificare se ci sono dei numeri dispari.
Il vettore che gli passi è costituito solamente da numeri dispari quindi non c'è nessun bisogno di fare questo controllo.
Prova a prendere un pezzo di carta ed eseguire i passaggi step by step, così capirai meglio a cosa servono...
Mi sembra ci sia qualcosa che non va nel programma, accetta in imput solo numeri pari e lo 0...
Ed anche il calcolo del massimo non funziona, però la cosa importante è che al momento non stai utilizzando alcun tipo di ricorsione, almeno in base alle definizioni che conosco e che ho scritto sopra
Io comunque ottengo questo come risultato, eseguendo quel programma:
Ed anche il calcolo del massimo non funziona, però la cosa importante è che al momento non stai utilizzando alcun tipo di ricorsione, almeno in base alle definizioni che conosco e che ho scritto sopra
Io comunque ottengo questo come risultato, eseguendo quel programma:
Inserisci il 1° numeri: 2 Inserisci il 2° numeri: 4 Inserisci il 3° numeri: 0 Inserisci il 4° numeri: 5 Process returned -1 (0xFFFFFFFF) execution time : 2.727 s Press ENTER to continue.
Inserisci il 1° numeri: 2 Inserisci il 2° numeri: 4 Inserisci il 3° numeri: 6 Inserisci il 4° numeri: 8 Inserisci il 5° numeri: 10 Il numero massimo vale: 0 Process returned 0 (0x0) execution time : 2.982 s Press ENTER to continue.
"floppyes":
Ciao!
Secondo te può andare bene? Funzionare ho visto che funziona, la ricorsione l'ho inserita e restituisce zero in caso non ci siano interi dispari.
Secondo me, se scrivi questo:
int massimo (int vett[dim], int j) { int max; //printf("Che valore c'è dentro max? %d", max); //Ti visualizza 0? for (i=0;i<dim;i++) if (vett[i]>max)max=vett[i]; return max; }
A te (ma non a me) darà lo stesso risultato di quello che hai scritto prima.
Che ambiente di sviluppo stai utilizzando? Da quello che ho capito da te le variabili intere vengono inizializzate a 0 nel momento della dichiarazione perchè ricordo di un esercizio dove non avevi inizializzato num ed esso era stato inizializzato a zero da solo e quindi l'esercizio terminava mentre da me continuava.
Ad esempio cosa succede se in questo codice tu volessi visualizzare il valore di max prima del for? Ti visualizzerebbe 0?
Comunque il tuo codice non va bene perchè se lo provi su un altro ambiente di sviluppo e gli passi un vettore vuoto non restituisce 0 ma il valore che si trova all'interno di vett[0] che da te sarà anche 0 ma da me no.
Inoltre quello che hai scritto non è auto-consistente:
La dimensione di quel vettore non è DIM ma è J e secondo me se provi a visualizzare i valori da vett[j] a vett[dim-1] saranno tutti 0 per il motivo che ho scritto sopra e cioè che nel tuo ambiente di sviluppo secondo me tutte le variabili intere sono inizializzate a 0.
Tra l'altro se vuoi controllare tutti i valori da 0 a DIM-1 non ha senso crearsi un vettore che ha solamente i numeri dispari e poi passaglierlo. Se vuoi fare quello che hai fatto nella funzione, dove controlli sempre un elemento è dispari, allora dal MAIN devi eliminare la parte in cui isoli tutti i valori dispari e passare alla funzione il vettore con tutti i valori che ha inserito l'utente, cioè anche con i pari.
E la cosa più importante in assoluto è che tu non stai usando la ricorsione mentre l'esercizio era sulla ricorsione.
Comunque se lancio il tuo codice mi risulta questo:
Il motivo è che prima di creare il vettore non hai inizializzato j=0;
A te risulta giusto perchè da te vengono automaticamente inizializzate a 0.
Inserisci il 1░ numeri: 8 Inserisci il 2░ numeri: 3 Inserisci il 3░ numeri: 2 Inserisci il 4░ numeri: 4 Inserisci il 5░ numeri: 9 Il numero massimo vale: 2686708 Process returned 0 (0x0) execution time : 6.343 s Press any key to continue.
Inserisci il 1░ numeri: 1 Inserisci il 2░ numeri: 3 Inserisci il 3░ numeri: 9 Inserisci il 4░ numeri: 5 Inserisci il 5░ numeri: 7 Il numero massimo vale: 2686708 Process returned 0 (0x0) execution time : 4.620 s Press any key to continue.
Inserisci il 1░ numeri: 2 Inserisci il 2░ numeri: 4 Inserisci il 3░ numeri: 8 Inserisci il 4░ numeri: 6 Inserisci il 5░ numeri: 8 Il numero massimo vale: 2686708 Process returned 0 (0x0) execution time : 5.647 s Press any key to continue.
Il motivo è che prima di creare il vettore non hai inizializzato j=0;
A te risulta giusto perchè da te vengono automaticamente inizializzate a 0.
Ciao!
Grazie mille per l'aiuto, riguardando i vostri codici ho capito che cos'è la ricorsione! Nel mio non è mai presente una ricorsione perchè non richiamo mai la stessa funzione. Ad esempio nel codice di atem ho la ricorsione perchè:
la funzione maxdisp richiama se stessa se j>0.
@atem: ho provato a seguire passo passo il programma. Fino alla riga 28 tutto ok!
Riga 35: se j vale 0, quindi se l'utente non ha immesso nessun numero dispari, allora la funzione maxdisp restituisce il valore contenuto in vett[0] che varrà 0.
Riga 36: se è stato inserito almeno un numero dispari, allora si passa alla funzione if.
In questo caso, mettiamo che j valga 3, il programma verifica che il valore di vett[3] sia maggiore del valore di vett[2], se lo è mi restituisce il valore di vett[3], altrimenti mi restituisce il valore di vett[2].
Poi continua a fare questa operazione fino a quando j vale 0, tutto ciò grazie alla ricorsione che richiamando la stessa funzione per i valori di j-1 arriva fino a j=0, e quindi tutti i numeri contenuti in vett[j] vengono controllati dalla funzione e si riesce a determinare il massimo.
Ma allora mettiamo sempre il caso che j valga 3, la funzione richiama se stessa fino ad arrivare a j = 0. In questo caso allora il programma mi restituisce vett[0], e quindi non dovrebbe in ogni caso restituirmi il primo valore di vett[j]?
Intendi sostituire la mia funzione massimo con quella che mi hai scritto? In questo caso mi esce un errore di conflitto.
Sono su mac, sto utilizzando CodeRunner per scrivere, compilare ed eseguire il codice. Tu che programma stai utilizzando per il codice c? In caso provo a cambiarlo, in teoria dovrei utilizzare devC++ però con questa app impiego meno tempo perchè scrivo ed eseguo nella stessa finestra senza passare da terminale.
Grazie ancora per l'aiuto
Ciaoo!
Grazie mille per l'aiuto, riguardando i vostri codici ho capito che cos'è la ricorsione! Nel mio non è mai presente una ricorsione perchè non richiamo mai la stessa funzione. Ad esempio nel codice di atem ho la ricorsione perchè:
int maxdisp (int vett[], int j) //funzione di tipo int { if (j==0) return vett[0]; if (j>0) { if (vett[j]> maxdisp(vett,j-1)) return vett[j]; else return maxdisp(vett, j-1); } return 0; }
la funzione maxdisp richiama se stessa se j>0.
@atem: ho provato a seguire passo passo il programma. Fino alla riga 28 tutto ok!
Riga 35: se j vale 0, quindi se l'utente non ha immesso nessun numero dispari, allora la funzione maxdisp restituisce il valore contenuto in vett[0] che varrà 0.
Riga 36: se è stato inserito almeno un numero dispari, allora si passa alla funzione if.
In questo caso, mettiamo che j valga 3, il programma verifica che il valore di vett[3] sia maggiore del valore di vett[2], se lo è mi restituisce il valore di vett[3], altrimenti mi restituisce il valore di vett[2].
Poi continua a fare questa operazione fino a quando j vale 0, tutto ciò grazie alla ricorsione che richiamando la stessa funzione per i valori di j-1 arriva fino a j=0, e quindi tutti i numeri contenuti in vett[j] vengono controllati dalla funzione e si riesce a determinare il massimo.
Ma allora mettiamo sempre il caso che j valga 3, la funzione richiama se stessa fino ad arrivare a j = 0. In questo caso allora il programma mi restituisce vett[0], e quindi non dovrebbe in ogni caso restituirmi il primo valore di vett[j]?
A te (ma non a me) darà lo stesso risultato di quello che hai scritto prima.
Intendi sostituire la mia funzione massimo con quella che mi hai scritto? In questo caso mi esce un errore di conflitto.
Che ambiente di sviluppo stai utilizzando?
Sono su mac, sto utilizzando CodeRunner per scrivere, compilare ed eseguire il codice. Tu che programma stai utilizzando per il codice c? In caso provo a cambiarlo, in teoria dovrei utilizzare devC++ però con questa app impiego meno tempo perchè scrivo ed eseguo nella stessa finestra senza passare da terminale.
Grazie ancora per l'aiuto
Ciaoo!
PS: ho provato ad rieseguire il codice che avevo postato ed esce anche a me il vostro errore, anche dichiarando la variabile j a zero 
Prima l'avevo modificato ed andava, poi ho aggiunto una riga ed esce l'errore. Comunque è sbagliato perchè manca sempre la ricorsione

Prima l'avevo modificato ed andava, poi ho aggiunto una riga ed esce l'errore. Comunque è sbagliato perchè manca sempre la ricorsione
Io uso Code::Blocks
No. Se j vale 0 vuol dire che è stato inserito esattamente un elemento e ovviamente visto che è l'unico sarà anche il massimo. Riguarda il MAIN, ho passato j-1 non j.
Osserva l'istruzione return vett[j]
Se la dimensione è 7, non posso dire return vett[7] visto che l'ultimo sarà 6 quindi io non gli ho passato la dimensione, ma la posizione dell'ultimo valore, cioè dimensione-1.
Il programma non controlla che vett[3] sia maggiore di vett[2] ma controlla se vett[3] è maggior del valore massimo dei precedenti elementi. Se è così ritorna vett[3] altrimenti ritorna il massimo di quelli precedenti.
Es:
vett[0]=7
vett[1]=5
vett[2]=9
vett[3]=3
Le operazioni sono queste:
A.vett[3] è maggiore del massimo fra i precedenti? Non so quale sia il massimo fra i precedenti (X).
B.vett[2] è maggiore del massimo fra i precedenti? Non so quale sia il massimo fra i precedenti (Y).
C.vett[1] è maggiore del massimo fra i precedenti? Non so quale sia il massimo fra i precedenti (Z).
Se J=0 allora il massimo (Z) è vett[0] che diventa "il massimo fra i precedenti (Z)"
Ora che conosciamo la prima incognita (Z) possiamo rispondere a tutte le domande che ci eravamo posti prima.
C. vett[1]> 7? No, allora Y=7
B. vett[2]> 7? Sì, allora X=9
A. vett[3]> 9? No, allora ritorna 9.
Ho risposto a tutte le domande, quindi ora conosco la soluzione e cioè il risultato finale è 9.
"floppyes":
Ciao!
Riga 35: se j vale 0, quindi se l'utente non ha immesso nessun numero dispari, allora la funzione maxdisp restituisce il valore contenuto in vett[0] che varrà 0.
No. Se j vale 0 vuol dire che è stato inserito esattamente un elemento e ovviamente visto che è l'unico sarà anche il massimo. Riguarda il MAIN, ho passato j-1 non j.
Osserva l'istruzione return vett[j]
Se la dimensione è 7, non posso dire return vett[7] visto che l'ultimo sarà 6 quindi io non gli ho passato la dimensione, ma la posizione dell'ultimo valore, cioè dimensione-1.
Riga 36: se è stato inserito almeno un numero dispari, allora si passa alla funzione if.
In questo caso, mettiamo che j valga 3, il programma verifica che il valore di vett[3] sia maggiore del valore di vett[2], se lo è mi restituisce il valore di vett[3], altrimenti mi restituisce il valore di vett[2].
Poi continua a fare questa operazione fino a quando j vale 0, tutto ciò grazie alla ricorsione che richiamando la stessa funzione per i valori di j-1 arriva fino a j=0, e quindi tutti i numeri contenuti in vett[j] vengono controllati dalla funzione e si riesce a determinare il massimo.
Ma allora mettiamo sempre il caso che j valga 3, la funzione richiama se stessa fino ad arrivare a j = 0. In questo caso allora il programma mi restituisce vett[0], e quindi non dovrebbe in ogni caso restituirmi il primo valore di vett[j]?
Il programma non controlla che vett[3] sia maggiore di vett[2] ma controlla se vett[3] è maggior del valore massimo dei precedenti elementi. Se è così ritorna vett[3] altrimenti ritorna il massimo di quelli precedenti.
Es:
vett[0]=7
vett[1]=5
vett[2]=9
vett[3]=3
Le operazioni sono queste:
A.vett[3] è maggiore del massimo fra i precedenti? Non so quale sia il massimo fra i precedenti (X).
B.vett[2] è maggiore del massimo fra i precedenti? Non so quale sia il massimo fra i precedenti (Y).
C.vett[1] è maggiore del massimo fra i precedenti? Non so quale sia il massimo fra i precedenti (Z).
Se J=0 allora il massimo (Z) è vett[0] che diventa "il massimo fra i precedenti (Z)"
Ora che conosciamo la prima incognita (Z) possiamo rispondere a tutte le domande che ci eravamo posti prima.
C. vett[1]> 7? No, allora Y=7
B. vett[2]> 7? Sì, allora X=9
A. vett[3]> 9? No, allora ritorna 9.
Ho risposto a tutte le domande, quindi ora conosco la soluzione e cioè il risultato finale è 9.
Ciao!
Grazie mille come sempre per l'ottima spiegazione, adesso è tutto molto più chiaro. Ho provato io a guardare un pò di esempi sul libro ma non avevo capito molto bene il ragionamento alla base!
Quindi quando mi viene chiesto di utilizzare una funzione con ricorsione, devo scrivere una funzione che si richiama in se stessa!
Grazie ancora! Adesso provo a fare altri esercizi simili, in caso chiederò ancora un aiutino
Ciaoo!
Grazie mille come sempre per l'ottima spiegazione, adesso è tutto molto più chiaro. Ho provato io a guardare un pò di esempi sul libro ma non avevo capito molto bene il ragionamento alla base!
Quindi quando mi viene chiesto di utilizzare una funzione con ricorsione, devo scrivere una funzione che si richiama in se stessa!
Grazie ancora! Adesso provo a fare altri esercizi simili, in caso chiederò ancora un aiutino

Ciaoo!
L'esempio classico di funzione ricorsiva che troverai pressoché ovunque è questo...
Diciamo che come nella funzione di prima per il massimo dispari, prima si mettono degli if per gestire i casi banali in cui il fattoriale vale 1, mentre poi si passa al caso standard, che in effetti rispecchia il modo in cui è definito...
Il consiglio è quello di provare ad eseguirlo con carta e penna per capire effettivamente la logica della ricorsione, anche se in questo caso discende direttamente da come è costruito il fattoriale
Diciamo che come nella funzione di prima per il massimo dispari, prima si mettono degli if per gestire i casi banali in cui il fattoriale vale 1, mentre poi si passa al caso standard, che in effetti rispecchia il modo in cui è definito...
Il consiglio è quello di provare ad eseguirlo con carta e penna per capire effettivamente la logica della ricorsione, anche se in questo caso discende direttamente da come è costruito il fattoriale

#include <stdio.h> int fatt(int n); int main() { int x; scanf("%d",&x); if(x<0) printf("Errore!Inserire un numero maggiore o uguale a zero!\n"); else printf("Il fattoriale di %d e' %d\n",x,fatt(x)); return 0; } int fatt(int n) { if(n==1||n==0) return 1; else return n*fatt(n-1); }
Ciao!
Grazie per l'esempio, in questo caso mettiamo che x valga 2, allora eseguo la ricorsione. Col pimo if chiedo se n è uguale a 1 o uguale a 0, però non so quanto vale n, quindi passo all'else, qui moltiplico 2 per il fattoriale di n-2.
Poichè n-2=1 allora eseguendo di nuovo il primo if trovo che n è uguale a 1, quindi mi restituisce 1. Allora il fattoriale di 2 è 2*1.
Se x vale 3 allora ottentevo:
n vale 1 o 0? Non lo so, allora eseguo n*fatt(n-1) quindi 3*fatt2
n vale 1 o 0? No allora eseguo n*fatt(n-1) quindi 3*2*fatt(1)
n vale 1 o 0? Si, allora ritorna 1, quindi 3*2*1
Ora è tutto chiaro, il problema è capire bene come scrivere il codice negli esercizi
Grazie
Ciaoo
Grazie per l'esempio, in questo caso mettiamo che x valga 2, allora eseguo la ricorsione. Col pimo if chiedo se n è uguale a 1 o uguale a 0, però non so quanto vale n, quindi passo all'else, qui moltiplico 2 per il fattoriale di n-2.
Poichè n-2=1 allora eseguendo di nuovo il primo if trovo che n è uguale a 1, quindi mi restituisce 1. Allora il fattoriale di 2 è 2*1.
Se x vale 3 allora ottentevo:
n vale 1 o 0? Non lo so, allora eseguo n*fatt(n-1) quindi 3*fatt2
n vale 1 o 0? No allora eseguo n*fatt(n-1) quindi 3*2*fatt(1)
n vale 1 o 0? Si, allora ritorna 1, quindi 3*2*1
Ora è tutto chiaro, il problema è capire bene come scrivere il codice negli esercizi

Grazie
Ciaoo

Riguardo all'esercizio iniziale io lo avrei fatto in questo modo. Il metodo è simile a Obidream, ma un po' più sintetico.
n è il numero di elementi del vettore.
int max(int *vett, int n) { if (n == 0) return 0; if (n == 1) return (vett[0] % 2 == 0)? 0 : vett[0]; int m = max(vett+1, n-1); if (vett[0] % 2 == 0) return m; else return (vett[0] > m)? vett[0] : m; }
n è il numero di elementi del vettore.
Nel caso in cui si elimini il valore finale invece di quello iniziale, bisogna tener conto che si toglie l'elemento vett[n-1] e non vett[n]. A mio avviso però è meglio usare il primo valore.
return (vett[0] > m)? vett[0] : m;
Ciao Vict, questa sintassi cosa significa?
Ricordo di averla incontrata una volta, ma ammetto di aver dimenticato tutto al riguardo...
