[C++] Non capisco perchè questa funzione è ricorsiva

BoG3
Ciao a tutti, in un esercizio dell'esame di programmazione 1 dice:



Poi nelle soluzioni, uscite la era dopo l'esame propone la funzione:

int* crea_vettore(int n){
  int *v = new int[n];
  numeri_esagonali(v, n, 0);
  return v;
}


come funzione ricorsiva.



Qua l'unica funzione ricorsiva mi sembra
numeri_esagonali
... non capisco perchè anche
crea_vettore
è da considerarsi ricorsiva!!??

Qualcuno me lo puo' spiegare?

Io ho cercato per buona parte del tempo di capire come creare dinamicamente un array e riempirlo in una funz ricorsiva...
dato che dice espressamente che deve essere ricorsiva sia la funzione crea_vettore che ogni altra funzione che in qualche modo ci ha a che fare (Nota 1). Ho anche tentato di farlo con 2 funzioni ricorsive ma... continuavo ad avere problemi.

Risposte
apatriarca
La funzione crea_vettore non è in effetti ricorsiva come hai giustamente osservato. Probabilmente l'idea che voleva trasmettere il professore era che il problema dovesse essere risolto dinamicamente e non che la specifica funzione dovesse esserlo. In effetti il problema è di fatto risolto nella funzione numeri_esagonali che è ricorsiva. Comunque puoi chiedere conferma al professore in modo da non ritrovarti all'esame davanti allo stesso dubbio.

BoG3
il prof ha risp:

Una funzione ricorsiva puo' esere (e questa cosa e'
molto frequente) una funzione che semplicemente si limita a chiamare
un'altra funzione ricorsiva ausiliaria con altri parametri (tipicamente, con
almeno in piu' un parametro su cui fare la ricorsione).


Quindi ... non avevo capito la definizione di funzione ricorsiva

Quinzio
Tipico esercizio che serve solo a confondere le idee e non insegna nulla di nuovo.

vict85
"BoG":
Quindi ... non avevo capito la definizione di funzione ricorsiva


No, semplicemente il tuo professore usa una definizione molto ampia di funzione ricorsiva che ha un qualche senso. Un processo di questo tipo:
funzione_A (...)
{
    condizioni;
    return funzione_B(...);
}

funzione_B (...)
{
    condizioni;
    return funzione_A(...);
}
è considerato un algoritmo ricorsivo anche se a rigore nessuna delle due funzioni prese singolarmente lo è. Inoltre si usano spesso funzioni che hanno il solo scopo di far partire la ricorsione (per nascondere l'implementazione della funzione all'utente o per far si che parta nel modo corretto).

D'altra parte la sua funzione fa una operazione distinta da quella che è propria della ricorsione quindi a mio avviso non è ricorsiva in nessun senso (chiama una funzione ricorsiva ma il suo scopo principale è quello di creare il vettore che fa in maniera diretta).

Tra l'altro non capisco l'amore dei professori per le funzioni ricorsive. Non hanno alcun vantaggio rispetto all'equivalente iterativo, specialmente in C++. Inoltre questa funzione è, a tutti gli effetti, un for mascherato da funzione ricorsiva.

Tra l'altro a rigore non sono sicuro che la nota 3 sia rispettata considerando che usa l'operatore new, che spesso è implementato usando malloc (che io sappia).

BoG3
che peccato, ad una soluzione come quella del prof c'ero arrivato anche io! infatti l'ho scartata al volo perchè non la consideravo ricorsive. peccato... ho preso 16... d'oh!

apatriarca
Un piccolo consiglio.. scrivere qualcosa è in generale meglio che scrivere nulla. Mal che vada ti avrebbe annullato l'esercizio perché non rispettava la richiesta, ma c'è sempre la possibilità che te lo valuti un po' più di zero..

BoG3
si, io ho scritto qualcosa:
ho risolto il problema ricorsivamente ma non sono stato in grado di incorporare anche la creazione e popolazione di un vettore dianamicamente quindi ho reindirizzato il risultato a schermo (dove tutto funzionava), commentando le parti che avrebbero dovuto lavorare sul vettore. Infatti mi hanno annullato l'esercizio perchè non ho fatto cio' che era richiesto. Andra' meglio la prossima volta!

BoG3
oggi durante l'esame lo ha detto che ha ricevuto diverse lamentele, simili alla mia e ha ribadito che per funzione ricorsiva lui intende una funzione senza cicli, quindi anche una funzione che semplicemente richiama una funzione ricorsiva.

ramy100689
"vict85":
[quote="BoG"]Quindi ... non avevo capito la definizione di funzione ricorsiva


No, semplicemente il tuo professore usa una definizione molto ampia di funzione ricorsiva che ha un qualche senso. Un processo di questo tipo:
funzione_A (...)
{
    condizioni;
    return funzione_B(...);
}

funzione_B (...)
{
    condizioni;
    return funzione_A(...);
}
è considerato un algoritmo ricorsivo anche se a rigore nessuna delle due funzioni prese singolarmente lo è. Inoltre si usano spesso funzioni che hanno il solo scopo di far partire la ricorsione (per nascondere l'implementazione della funzione all'utente o per far si che parta nel modo corretto).

D'altra parte la sua funzione fa una operazione distinta da quella che è propria della ricorsione quindi a mio avviso non è ricorsiva in nessun senso (chiama una funzione ricorsiva ma il suo scopo principale è quello di creare il vettore che fa in maniera diretta).

Tra l'altro non capisco l'amore dei professori per le funzioni ricorsive. Non hanno alcun vantaggio rispetto all'equivalente iterativo, specialmente in C++. Inoltre questa funzione è, a tutti gli effetti, un for mascherato da funzione ricorsiva.

Tra l'altro a rigore non sono sicuro che la nota 3 sia rispettata considerando che usa l'operatore new, che spesso è implementato usando malloc (che io sappia).[/quote]

Quelle due funzioni sono mutuamente ricorsive, ma crea_vettore non può essere considerata ricorsiva, senza ombra di dubbio. L' unico motivo la funzione A è ricorsiva, è che è definita tramite una funzione che è definita in termini della funzione A, quindi in fin dei conti è definita in termini di se stessa (ed è questa la definizione di ricorsione).

BoG3
ma se B avesse richiamato una terza funzione C che a sua volta richiamava A, sarebbe ancora considerata ricorsiva? importa il "numero di passaggi" prima di ritornare alla funzione A?

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