If sequenziali in un colpo solo



La serie di if sequenziali è un costrutto che viene usato molto di frequente e consiste in una sequenza di if dove l’i-esimo viene eseguito solo nel caso tutti i precedenti abbiano avuto risposta false nella condizione.

Per esempio supponiamo di dover stampare a video una certa frase a seconda di un valore calcolato pseudo-casualmente. La pseudo-casualità viene gestita con la serie di if.

int limit_1 = 10, limit_2 = 20, limit_3 = 30;
double choice = rand() % 40;
if (choice < limit_1)
{
cout << "basso" << endl;
}
else if (choice < limit_2)
{
cout << "normale" << endl;
}
else if (choice < limit_2)
{
cout << "medio" << endl;
}
else
{
cout << "alto" << endl;
}

In pratica la scelta casuale viene “dirottata” verso certi valori attraverso le variabili limite che determina quindi la pseudo-casualità.

Il problema è che diventa lunga la fase di scrittura nel caso di molte scelte una dopo l’altra e dal punto di vista computazionale il numero di confronti nel caso peggiore diventa uguale al numero di casi possibili. Nell’esempio mostrato i casi possibili sono 4 (+1 rispetto ai limiti).

Allora per diminuire i numeri dei confronti e rendere deterministico il numero di confronti fatti si può vedere il problema da un punto di vista un po’ diverso.

Per prima cosa si definisce il vettore contenente i valori possibili (in questo caso le stringhe da stampare).

char *select[4] = { "basso", "normale", "medio", "alto" };

Ora è necessario trovare il metodo per indirizzare il vettore select in base alla variabile choice. Riferendoci all’esempio si deve fare in modo che quando chioce sia minore di limit_1 si vada a selezionare il contenuto di select all’indice 0, quando choice è compreso tra limit_1 e limit_2 allora si estrae select[1] e cosi via. Questo si ottiene sommando la negazione di tutti i confronti degli if.

!(choice < limit_1) + !(choice < limit_2) + !(choice < limit_3)

Con questa sommatoria si trova il risultato sperato e quindi si può riformulare il problema nelle sequenti righe di codice.

char *select[4] = { "basso", "normale", "medio", "alto" };
cout << select[!(choice < limit_1) + !(choice < limit_2) + !(choice < limit_3)

Con queste due righe si ottiene lo stesso risultato del primo esempio. Rende molto più veloce lo sviluppo di if sequenziali a discapito di una minore leggibilità e si ottiene anche un determinismo nel numero di operazioni eseguite. Rimane il problema della complessità compitazionale dove si trova un punto critico dovuto al fatto che bisogna fare tutti i confronti in ogni caso.

Alessandro Carrega

Annunci sponsorizzati:
Condividi su Facebook Condividi su Twitter!
Pinterest