Visualizzazione dei risultati da 1 a 9 su 9

Discussione: ricorsione c++

Hybrid View

  1. #1
    Un'altra possibile soluzione

    codice:
    double media( struct tipo1 *p, int n, double &mediaVoti )
    {
        if( n )
        {
            cout<<"Nome : "<<p[n].nome<<" \t"<<p[n].cognome<<" \t"<<p[--n].voto<<endl;
            media( p, n, (mediaVoti += p[n].voto) );
        }
        return mediaVoti / ++n;
    }

    da richiamare in questo modo


    codice:
        double mediaVoti = 0.;
        mediaVoti = media( p, N, mediaVoti);
    01010011 01100001 01101101 01110101 01100101 01101100 01100101 01011111 00110111 00110000
    All errors are undocumented features waiting to be discovered.

  2. #2
    Utente di HTML.it L'avatar di Scara95
    Registrato dal
    Jul 2009
    residenza
    Zimella (VR)
    Messaggi
    2,589
    Quote Originariamente inviata da Samuele_70 Visualizza il messaggio
    Un'altra possibile soluzione

    codice:
    double media( struct tipo1 *p, int n, double &mediaVoti )
    {
        if( n )
        {
            cout<<"Nome : "<<p[n].nome<<" \t"<<p[n].cognome<<" \t"<<p[--n].voto<<endl;
            media( p, n, (mediaVoti += p[n].voto) );
        }
        return mediaVoti / ++n;
    }

    da richiamare in questo modo


    codice:
        double mediaVoti = 0.;
        mediaVoti = media( p, N, mediaVoti);
    NO, decisamente no.
    Pessima.
    Se utilizzi una variabile per mantenere lo stato perdi tutto.
    Il tuo codice è pieno di stati!!

    Inoltre questa riga è esposta a ub (almeno per le mie conoscenze):
    codice:
    cout<<"Nome : "<<p[n].nome<<" \t"<<p[n].cognome<<" \t"<<p[--n].voto<<endl;
    "Quid enim est, quod contra vim sine vi fieri possit?" - Cicerone, Ad Familiares

  3. #3
    Utente di HTML.it L'avatar di Scara95
    Registrato dal
    Jul 2009
    residenza
    Zimella (VR)
    Messaggi
    2,589
    Piuttosto
    codice:
    int sum(const struct tipo1 *p, n, acc) {
      if(n == 0)
        return acc;
      else
        return sum(p, n-1, acc + p[n-1]);
    }
    
    double media(const struct tipo1 *p, n) {
      return sum(p, n, 0) / ((double)n);
    }
    "Quid enim est, quod contra vim sine vi fieri possit?" - Cicerone, Ad Familiares

  4. #4
    Quanta enfasi scara , l'unico rischio nel mio codice, così come nei tuoi è una vulnerabilità del tipo division by zero, ma facilmente ovviabile.

    Quote Originariamente inviata da Scara95 Visualizza il messaggio
    Piuttosto
    codice:
    int sum(const struct tipo1 *p, n, acc) {
      if(n == 0)
        return acc;
      else
        return sum(p, n-1, acc + p[n-1]);
    }
    
    double media(const struct tipo1 *p, n) {
      return sum(p, n, 0) / ((double)n);
    }
    p è un puntatore a strutture tipo1, forse volevi scrivere acc + p[n-1].voto
    01010011 01100001 01101101 01110101 01100101 01101100 01100101 01011111 00110111 00110000
    All errors are undocumented features waiting to be discovered.

  5. #5
    Utente di HTML.it L'avatar di Scara95
    Registrato dal
    Jul 2009
    residenza
    Zimella (VR)
    Messaggi
    2,589
    Vabbè, quell'errore era banale.

    Il punto non era che il tuo codice non funziona. (a parte quello che secondo me è ub)
    Il punto è che ha side effects.
    Mantiene uno stato.

    Il risultato non dipende solo dai parametri passati

    Esempio:
    Supponiamo di trovarci in ambiente concorrente (questo ovviamente non è c++, ma un pseudolinguaggio):
    codice:
    double zero = 0.0;
    spawn {cout << media(p1, 4, zero) << endl;}
    spawn {cout << media(p2, 4, zero) << endl;}
    Supponendo di conoscere p1, p2 e che cout sia sincronizzato in modo da dare un output prevedibile (al più si scambia l'ordine delle righe),
    sai dirmi l'output?

    Il tuo codice è antieducativo. Inoltre mantenere uno stato esterno già di per sé va contro i principi della programmazione "funzionale".

    Aggiungo che mentre le mie due implementazioni (corrette a meno di un .voto) sono ottimizzabili in un ciclo in quanto ricorsive in coda (tail recursive), la tua non lo è e si mangerà lo stack.

    Insomma, ci sono molti buoni motivi per evitare un implementazione simile. Sicuramente un professore che cerca di insegnare a pensare ricorsivamente la considererebbe errata (a livello pratico).

    In sostanza la tua implementazione non da nessun vantaggio ma da molti problemi.
    La mia di certo non da vantaggi rispetto a un'implementazione nativa con un for, ma non da neanche problemi. (sarebbe trascurabile anche il "mangiarsi lo stack" a livello educativo, ma non il resto)
    Ultima modifica di Scara95; 25-04-2015 a 14:49
    "Quid enim est, quod contra vim sine vi fieri possit?" - Cicerone, Ad Familiares

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.