Funzione ricorsiva
Ragazzi ho un esercizio in cui devo disegnare un "<" con gli asterichi,con una funzione ricorsiva..
Ho qualche problema nella risoluzione,qualcuno sa come possso fare??
Vi posto il codice,ciò che ho fatto..
Grazie!!
Ho qualche problema nella risoluzione,qualcuno sa come possso fare??
Vi posto il codice,ciò che ho fatto..
void stampamin(int N,int l=0,int k=0){ if(N==0)return; if(l<N/2){ for(int i=0;i<N/2-k+1;i++)cout<<" "; cout<<"*"<<endl; } else{ for(int i=0;i<k-N/2;i++)cout<<" "; cout<<"*"<<endl; } return stampamin(N-1,l+1,k+1); }
Grazie!!
Risposte
ma la tua funzione stampa solo spazi e asterischi in linea retta (mi sembra).
per risolvere il tuo problema io utilizzere i semplici caratteri speciali del vetusto ma grande codice ASCII (ritorno carrello, tab, ecc...)
- portarti a distanza di tot spazi (utilizzi tab orizzontale)
- inizi a stampare asterischi ricorsivamente, stampando insieme ritorno carrello e ritorno a capo.
questo per /
poi ripeti nell'altro senso stampi in senso contrari e qua invece usi spazio e stamperai \.
prova a scriverlo in codice
EDIT:
ragionamento a ciclo, sbagliato per questo problema.
per risolvere il tuo problema io utilizzere i semplici caratteri speciali del vetusto ma grande codice ASCII (ritorno carrello, tab, ecc...)
- portarti a distanza di tot spazi (utilizzi tab orizzontale)
- inizi a stampare asterischi ricorsivamente, stampando insieme ritorno carrello e ritorno a capo.
questo per /
poi ripeti nell'altro senso stampi in senso contrari e qua invece usi spazio e stamperai \.
prova a scriverlo in codice

EDIT:
ragionamento a ciclo, sbagliato per questo problema.
Mah che stampa una linea fortunatamente no
Questo é quello che ottengo compilando quel codice.
Riguardo il metodo da te citato non credo di aver capito,esattamente cosa dovrei fare.
Anche io uso il ritorno carrello é gli spazi bianchi
Grazie

Questo é quello che ottengo compilando quel codice.
Riguardo il metodo da te citato non credo di aver capito,esattamente cosa dovrei fare.
Anche io uso il ritorno carrello é gli spazi bianchi
Grazie
Quando si richiama un metodo ricorsivo esistono due fasi, una discendente e una ascendente (i nomi me li sto inventando al momento ma immagino ci siano dei termini più corretti che non ho modo di verificare adesso). Nella fase discendente il metodo viene richiamato fino ad arrivare al caso base, mentre in quella ascendente si utilizzano i risultati ottenuti dalle chiamate ricorsive per fare ulteriore lavoro. Invece di fare lavoro solo in una delle due fasi (normalmente quella discendente), è nel tuo caso più conveniente farlo in entrambe (in altri casi e altri linguaggi è invece conveniente farlo nella fase discendente in modo da trasformarlo in un ciclo). La funzione che stampa il '<' avrebbe più o meno l'aspetto seguente:
if n == 0 stampa * else stampa n spazi stampa * richiama metodo con n-1 stampa n spazi stampa *
Grazie adesso ci provo,avresti qualche buon libro in riguardo questo tipo di ricorsioni(in mezzo)??oppure anche dispense da consigliarmi..
Grazie.
Grazie.
@Gianni91:
uuh lascia stare ciò che ho scritto.
Ho completamente saltato la parola "ricorsiva"... Ho ragionato con un semplice ciclo, chiedo venia
uuh lascia stare ciò che ho scritto.
Ho completamente saltato la parola "ricorsiva"... Ho ragionato con un semplice ciclo, chiedo venia

no problem...
qualche idea ricorsiva??
qualche idea ricorsiva??

Non credo che ci siano libri che spiegano questa idea, non essendo per niente diversa da quella della normale ricorsione. Viene in effetti usata spesso. Considera per esempio la definizione ricorsiva del fattoriale:
\[
\begin{cases}
0\,! = 1 \\
n\,! = (n-1)\,! \, n \\
\end{cases}
\]
In quella che ho chiamato la fase discendente si decrementa il numero n per poi richiamare il fattoriale e in quella ascendente si moltiplica il fattoriale di \(n-1\) con \(n\). Altri esempi più simili a questo si incontrano in alcuni algoritmi sugli alberi (ma non sono certo che tu abbia studiato gli alberi).
Per mettere alla prova la mia versione ho implementato il seguente breve programma in haskell.
Eseguendolo ottengo
Sostituendo il 5 nel main con un 6 ottengo invece
Nota che in realtà è tutto ricorsivo in questa versione essendo ricorsive anche le funzioni replicate (che crea una lista lunga come il primo argomento e contenenti copie del secondo - in haskell non ci sono parentesi intorno ai parametri delle funzioni..), sia l'operatore ++ che serve per concatenare due liste (in questo caso due stringhe).
P.S. C'è uno strano bug nella visualizzazione dei risultati nel forum e ho dovuto aggiungere i _ che non sono presenti nell'output originale. In caso contrario non mi stampava gli spazi.
\[
\begin{cases}
0\,! = 1 \\
n\,! = (n-1)\,! \, n \\
\end{cases}
\]
In quella che ho chiamato la fase discendente si decrementa il numero n per poi richiamare il fattoriale e in quella ascendente si moltiplica il fattoriale di \(n-1\) con \(n\). Altri esempi più simili a questo si incontrano in alcuni algoritmi sugli alberi (ma non sono certo che tu abbia studiato gli alberi).
Per mettere alla prova la mia versione ho implementato il seguente breve programma in haskell.
stampamin n | n == 0 = return () | n == 1 = putStrLn "*" | n > 1 = do let riga = replicate (div (n-1) 2) ' ' ++ "*" putStrLn riga stampamin (n-2) putStrLn riga | True = error "n deve essere un numero positivo." main = stampamin 5
Eseguendolo ottengo
* _* * _* *
Sostituendo il 5 nel main con un 6 ottengo invece
* _* * * _* *
Nota che in realtà è tutto ricorsivo in questa versione essendo ricorsive anche le funzioni replicate (che crea una lista lunga come il primo argomento e contenenti copie del secondo - in haskell non ci sono parentesi intorno ai parametri delle funzioni..), sia l'operatore ++ che serve per concatenare due liste (in questo caso due stringhe).
P.S. C'è uno strano bug nella visualizzazione dei risultati nel forum e ho dovuto aggiungere i _ che non sono presenti nell'output originale. In caso contrario non mi stampava gli spazi.
Innanzitutto grazie per la spiegazione cosi completa,
riguardo il codice.Il comando "putStrLn",é del c,perché io ho fatto c++,dovrebbe essere il cout ???
Perché non vedo nessuna funzione con quel nome..
riguardo il codice.Il comando "putStrLn",é del c,perché io ho fatto c++,dovrebbe essere il cout ???
Perché non vedo nessuna funzione con quel nome..

putStrLn è una funzione standard in haskell che stampa una stringa a video e va a capo. Corrisponde alla funzione puts del C, ma può essere "simulata" utilizzando iostream aggiungendo << endl dopo aver stampato la stringa. Ma in C++, la parte del codice che stampa la stringa con gli spazi e l'asterisco l'avrei implementata con un ciclo (o con una corrispondente funzione ricorsiva). In effetti, è possibile che il codice macchina generato da quel codice haskell corrisponda al ciclo che stampa i singoli caratteri uno per volta (in haskell il codice subisce trasformazioni più radicali che in C++ essendo molto più astratto). Avrei insomma scritto (manca il codice intorno con i vari if):
int nzeri = (n-1)/2; for (int i = 0; i < nzeri; ++i) cout << ' '; cout << '*' << endl; stampamin(n-2); for (int i = 0; i < nzeri; ++i) cout << ' '; cout << '*' << endl;
Perfetto,capito..
Adesso ci ragiono un pò su questa funzione.
Grazie per l'aiuto
Adesso ci ragiono un pò su questa funzione.
Grazie per l'aiuto
