for imbriqués, break, continue, goto : grmpf ?
Bonjour,
J'ai plusieurs boucles imbriquées.
Je souhaite, dans un test par exemple au niveau 3 d'imbrication, décider de sortir de la boucle de niveau 3 et de la niveau 2.
Comment faire ?
Voici un exemple :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
|
// On lit donc les questions du premier animal
for (int i = Animals[0].Questions.Count - 1; i >= 0; i--)
{
// Et on vérifie qu'elle est présente sur les autres animaux
for (int j = Animals.Count - 1; j > 0; j--)
{
bool found = false;
for (int k = Animals[j].Questions.Count - 1; k >= 0; k--)
{
if (Animals[j].Questions[k].Id == Animals[0].Questions[i].Id)
{
found = true;
if (Animals[j].Questions[k].IsTrue != Animals[0].Questions[i].IsTrue)
{
goto KeepQuestion;
}
}
}
if (!found)
goto KeepQuestion;
}
// On supprime la question
for (int j = Animals.Count - 1; j >= 0; j--)
{
for (int k = Animals[j].Questions.Count - 1; k >= 0; k--)
{
if (Animals[j].Questions[k].Id == Animals[0].Questions[i].Id)
{
if (DEBUG)
{
Console.WriteLine("On vire la question {0} de l'animal {1}", Animals[j].Questions[k].Name, Animals[j].Name);
}
Animals[j].Questions.RemoveAt(k);
break;
}
}
}
KeepQuestion:
DoNothing();
} |
J'ai été contraint de mettre de "goto" :cry: pour pouvoir rentrer dans le cas "on garde la question".
Et vu qu'un label utilisé par un "goto" doit impérativement être suivit par au moins une instruction, j'ai dû créer une fonction "DoNothing()" qui ne fait rien :aie:
Bref, ce bout de code me fout la gerbe, et je me demande bien comment le corriger.
En BASIC par exemple, on peut faire un "NEXT i", qui va faire un "continue" mais non pas dans la boucle courante, mais dans la boucle qui porte sur la variable i. C'est sale, mais quand même moins que ma bidouille...
Il y a bien la solution en créant 36000 variables booléennes, mais j'ai pas non plus envie que mon code devienne imbittable, avec des "if" dans tous les sens qui n'arrangeront d'ailleurs rien aux performances...
Dans mon cas, tous les goto que j'ai utilisé pourraient être remplacés par des "continue", avec un paramètre qui permettrait de dire que je veux continuer mon premier niveau de for, par ceux qui sont à l'intérieur.
Bon, ben un booléen finalement c'est la solution
Hmmmmm
Bon, ben en ajoutant un booléen, j'arrive à m'en sortir finalement...
Comme quoi, expliquer son problème, c'est le meilleur moyen d'y trouver une solution :ccool:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
|
// On lit donc les questions du premier animal
bool keepQuestion;
for (int i = Animals[0].Questions.Count - 1; i >= 0; i--)
{
keepQuestion = false;
// Et on vérifie qu'elle est présente sur les autres animaux
for (int j = Animals.Count - 1; j > 0; j--)
{
bool found = false;
for (int k = Animals[j].Questions.Count - 1; k >= 0; k--)
{
if (Animals[j].Questions[k].Id == Animals[0].Questions[i].Id)
{
found = true;
if (Animals[j].Questions[k].IsTrue != Animals[0].Questions[i].IsTrue)
{
keepQuestion = true;
break;
}
}
}
if (!found)
{
keepQuestion = true;
break;
}
}
if (keepQuestion)
{
continue;
}
// On supprime la question
for (int j = Animals.Count - 1; j >= 0; j--)
{
for (int k = Animals[j].Questions.Count - 1; k >= 0; k--)
{
if (Animals[j].Questions[k].Id == Animals[0].Questions[i].Id)
{
if (DEBUG)
{
Console.WriteLine("On vire la question {0} de l'animal {1}", Animals[j].Questions[k].Name, Animals[j].Name);
}
Animals[j].Questions.RemoveAt(k);
break;
}
}
}
} |