I cicli annidati

Fino ad adesso abbiamo studiato i cicli, poi applicabili anche agli array.

Hai mai provato ad inserire un ciclo dentro l’altro per vedere cosa succede?

Come si formano i cicli annidati?

I cicli annidati, come già accennato, consistono nell’inserire un ciclo dentro un altro ciclo.

Ad esempio:

for (int i=0;i<numElem;i++) {
	
	<blocchi>
	
	for (int j=0;j<numElem;j++) {
		
		<blocchi>
		
	}
	
	<blocchi>
}

Oppure:

for (int i=0;i<numElem;i++) {
	
	<blocchi>
	
	while(f>0) {
		
		<blocchi>
		
		do {
			<blocchi>
		} while (f>0);
		
		<blocchi>
		
	}
}

Qualunque ciclo può essere inserito dentro un altro ciclo, e più cicli possono essere inseriti dentro altri cicli.

Occhio, non inserirne troppi!

Spesso, quando un programma non funziona, si ha la tentazione di inserire molti cicli annidati.

Spesso, la soluzione corretta si ottiene utilizzando due, tre cicli annidati più raramente. Ma quando ce ne sono già quattro, potrebbe non essere la via più semplice. Potrebbe anche funzionare, ma ricorda che più volte ripeti un ciclo, più memoria occupi e più rallenta il processo. E soprattutto, potrebbe essere sbagliato!

Quindi, stai attento!

Qualche esempio

Prendiamo come esempio questo esercizio: scrivere un programma che verifica se in un array di int ci sono elementi che si ripetono.

Per risolvere questo, devo trovare un modo per poter scorrere tutto l’array, tenendo però salvato l’elemento da confrontare con gli altri. Questo non è ovviamente possibile con un solo ciclo for, allora ecco che entra in gioco il doppio ciclo:

#include <iostream>

using namespace std;

int main() {
	int v[] = {1, 3, 5, 3, 6, 7};
	bool trovato = false;
	
	for (int i=0;i<6 && trovato==false;i++) { //ottimizzazione
		for (int j=0;j<6;j++) {
			if (i!=j) {
				if (v[i] == v[j]) {
					trovato = true;
				}
			}
		}
	}
	
	if (trovato==true) {
		cout<<"Nel vettore sono presenti elementi uguali";
	} else {
		cout<<"Il vettore non contiene elementi uguali";
	}
	
	return 0;
}

Seguiamo l’esecuzione del programma passo per passo:

  1. Entra nel primo ciclo for (contatore i);
  2. Entra nel secondo ciclo (contatore j);
  3. Verifica se il contatore i è uguale al contatore j;
  4. Se è vero, passa allo step 6 saltando il 5. Se è falso, prosegue;
  5. Controlla se il valore contenuto nella posizione i del vettore è uguale a quello contenuto in posizione j. Se i due valori sono uguali, trovato va a true, altrimenti rimane false;
  6. Termina il secondo ciclo, e riparte dal primo, incrementando la i, e così via, fino a quando trovato è uguale a true o fino a quando entrambi i cicli hanno terminato.

In questo modo, ogni volta che parte il primo ciclo si tiene salvata la variabile v[i], e con il secondo ciclo si verifica se v[j] è uguale.


Ci sono molti casi in cui si richiede l’utilizzo di più cicli annidati. Uno tra i tanti è per l’utilizzo delle matrici, che vedrai più avanti.

Ci sono altri esercizi un po’ più interessanti e grafici dove è richiesto l’utilizzo di cicli annidati.

Ad esempio, proviamo a riprodurre questa figura:

****
****
****
****
****
****

Questo è un rettangolo 4*6. Come facciamo a riprodurlo? Ovviamente, medianti l’utilizzo di due cicli for annidati, uno che si occuperà della base e l’altro che si occuperà della lunghezza:

#include <iostream>

using namespace std;

int main() {
	
	for (int i=0;i<6;i++) {
		for (int j=0;j<4;j++) {
			cout<<"*";
		}
		cout<<endl;
	}
	
}

Come vedi, il programma è molto semplice. Occhio a non invertire le condizioni!


Un altro esempio di figura da riprodurre è questo:

A
AA
AAA
AAAA
AAAAA

Questa volta un triangolo. Soluzione:

#include <iostream>

using namespace std;

int main() {
	
	for (int i=0;i<5;i++) {
		for (int j=0;j<=i;j++) {
			cout<<"A";
		}
		cout<<endl;
	}
	
}

Ora sei pronto per qualche esercizio, ma prima vediamo alcune funzioni di libreria!