2013-05-23 12 views
5

Sto provando a lavorare su un programma che ha una funzione il cui parametro è un vettore di stringa. Voglio usare ricorsiva in quella funzione, ma ogni volta che la funzione viene chiamata, voglio cambiare il parametro di dire ad esempioTieni traccia di quante volte è stata chiamata una funzione ricorsiva in C++

fun(stringArray[i]) 

dove i è il numero di volta che la funzione è stata chiamata.

Quindi in modo più semplice qualcosa come seguire. Ma ho bisogno di tenere traccia di quante volte è stata eseguita la funzione divertente.

void fun(){ 
    cout<<hi; 
    if(x!=10) 
    fun() 
} 

int main(){ 

    fun(); 
} 

In questo diciamo che voglio stamparlo solo 10 volte, quindi vuole avere un varible che incrementa, e quando raggiunge 10, si ferma. Quindi, in generale, cosa posso fare per tenerne traccia? Ho provato a utilizzare variabili globali ma non sembrano funzionare con le funzioni. Eventuali suggerimenti?

+2

È possibile aggiungere un parametro e incrementarlo durante la ricorsione. – chris

+0

Consiglio vivamente di dare un'occhiata al mio sondaggio –

risposta

8

ho visto un bel casino qui, quindi ho deciso di chiarire le cose.

Soluzione 0: Statico Variabile

Si consideri il codice proposto con una modifica leggera

#include<iostream> 
using namespace std; 

void fun() 
{ 
    static int count=1; 
    count++; 
    cout << "fun() is called " << count << " times" << endl; 
    if(count<=10) 
    { 
      fun(); 
    } 
} 

int main() 
{ 
    cout << "first call" << endl; 
    fun(); 
    cout << "second call" << endl; 
    fun(); 
    cout << "third call" << endl; 
    fun(); 
} 

E questo è l'output:

first call 
fun() is called 2 times 
fun() is called 3 times 
fun() is called 4 times 
fun() is called 5 times 
fun() is called 6 times 
fun() is called 7 times 
fun() is called 8 times 
fun() is called 9 times 
fun() is called 10 times 
fun() is called 11 times 
second call 
fun() is called 12 times 
third call 
fun() is called 13 times 

Come si può vedere l'utilizzo di variabili statiche potrebbero portare ad alcuni errori terribili.

Qui avete una funzione one shot che vi causerà un grande dolore in futuro.

Inoltre l'utilizzo di variabili statiche portano a un codice illeggibile che è soggetto ad errori

Basta non farlo!

Soluzione 1: variabile passata per valore

Considerate questo codice:

#include <iostream> 
using namespace std; 

void fun(int i){ 
    cout<<i<<endl; 
    if(i!=3) { 
     i++; 
     fun(i); 
     fun(i); 
    } 
} 

int main(){ 
    fun(0); 
} 

Questa è l'uscita:

0 
1 
2 
3 
3 
2 
3 
3 
1 
2 
3 
3 
2 
3 
3 

Come si può vedere l'uscita non è il numero di volte che la funzione è chiamata

Soluzione 2: variabile passata per riferimento

#include <iostream> 
using namespace std; 

void fun(int& x){ 
    if(x>=10) 
     return; 
    ++x; 
    cout << x << endl; 
    fun(x); 
} 

void funEntry(){ 
    int x = 0; 
    cout << "Entry point" << endl; 
    fun(x); 
} 

int main(){ 
    funEntry(); 
    funEntry(); 
} 

stamperà

Entry point 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 

Questo approccio funziona anche con qualche modello ricorsivo più esotiche come questo

#include <iostream> 
using namespace std; 

void fun(int i, int& x){ 
    if(i>=4) 
     return; 
    ++x; 
    cout << i << " " << x << endl; 
    fun(i+1,x); 
    fun(i+2,x); 
} 

void funEntry(){ 
    int x = 0; 
    cout << "Entry point" << endl; 
    fun(0,x); 
} 

int main(){ 
    funEntry(); 
    funEntry(); 
} 

uscita:

Entry point 
0 1 
1 2 
2 3 
3 4 
3 5 
2 6 
3 7 
Entry point 
0 1 
1 2 
2 3 
3 4 
3 5 
2 6 
3 7 
+0

Grazie mille per le informazioni dettagliate! – bachkoi32

-1

utilizzare la variabile statica all'interno della funzione ricorsiva. statico int i = 0; e all'inizio della funzione, diciamo i ++.

ogni volta che viene chiamata la funzione, questo verrà incrementato. e se il valore di I diventa 10, puoi terminare.

+1

Funziona, ma è necessario ricordarsi di resettarlo all'uscita e sperare che la funzione non venga chiamata da più thread contemporaneamente. – chris

+0

puoi anche racchiudere i bit all'interno della funzione con un flag statico che dice che c'è un thread in esso. Questo flag è impostato su false. Quando entrate nella funzione, fate prima un po 'di tempo (flag) {}, e non appena oltrepassate il ciclo while impostate il flag su true, e quando avete finito la funzione impostate nuovamente il flag su false. Ovviamente un modo migliore sarebbe utilizzare un oggetto kernel come un mutex invece di un flag, in modo che l'altro thread non stia girando i cicli della CPU per niente. – hvanbrug

1

se è necessario rendere ricorsivo ...

void fun(int i){ 

    cout<<hi; 
    if(i!=10) { 
     i++; 
     fun(i); 
    } 
} 

int main(){ 

    fun(0); 
} 

Speranza che aiuta?

+0

La soluzione di Sanish è più elegante della mia. – theshadow124

5

Aggiungere una variabile static come contatore.

#include<iostream> 
using namespace std; 

void fun() 
{ 
    static int count=1; 
    count++; 
    cout << "fun() is called " << count << " times" << endl; 
    if(count<=10) 
    { 
      fun(); 
    } 
} 

int main() 
{ 
    fun(); 
} 

static variabili sono inizializzate solo una volta e il valore viene conservato tra le chiamate di funzione. Vedere questo link http://en.wikipedia.org/wiki/Static_variable

+1

Forse 'static int count = 0;' sarebbe meglio –

+0

@EdHeal - grazie, intialized 'count' a 1 così che' fun() 'sarà chiamato 10 volte come richiesto :) – Sanish

+2

Come hai gestito più chiamate al divertimento() in principale? –

1
void fun(int& x){ 
    if(x>=10) 
     return; 
    ... Do something 
    ++x; 
    fun(x); 
} 

Si consiglia di utilizzare un riferimento a una variabile esterna

Se si passa il contatore per valore non è possibile effettuare chiamate multiple nella stessa funzione

Problemi correlati