J'ai une classe d'objets et j'ai besoin de comparer une propriété de chaque objet à la même propriété de tous les autres objets. S'ils correspondent, le code doit faire quelque chose. Il en résulte deux boucles for pour parcourir les objets pour obtenir cette propriété, et dans la seconde boucle for, une troisième boucle for traverse les éléments de la propriété (qui est un vecteur) pour les comparer. . S'ils correspondent, j'ai besoin de la boucle la plus externe pour abandonner l'itération actuelle et passer à la suivante (je veux seulement que la première correspondance avec un autre objet soit prise en compte).
J'ai étudié les instructions 'goto' et créé une structure do {} while (), mais je n'ai pas pu les implémenter de manière à obtenir le résultat souhaité. Ce dont j'ai besoin, c'est quelque chose comme une instruction 'continue' pour la boucle la plus externe basée sur ce qui se passe dans l'instruction conditionnelle dans la boucle la plus interne.
Quelle serait la bonne méthode pour y parvenir et comment devrait-elle être mise en œuvre?
Edit: à côté de la réponse que j'ai acceptée, je recommanderais également la réponse de Martin Bonner, qui fonctionne également parfaitement et ne repose pas sur goto.
for (int i = 0; i < max; i++){
Object & object1 = system.getAgent(i);
VectorOfStrings object_property1 = object1.getProperty();
for (int j = i + 1; j < max; j++){
Object & object2 = system.getObject(j);
VectorOfStrings object_property2 = object2.getProperty();
for (unsigned int k = 0; k < object_property1.size(); k++){
if (object_property1[k] == object_property2[k]){
//do something
break; //this aborts the inner most loop
//Additionally, I need the outer most loop to move on one iteration
}
}
}
}
Donc, si l'instruction conditionnelle dans la boucle "k" est remplie, je veux que la boucle "i" abandonne l'itération en cours et passe à la suivante.
De plus, comme je suis nouveau, le code peut être inélégant, mais veuillez vous concentrer sur ce problème spécifique dans vos réponses! À moins qu'une restructuration générale du code ne soit la solution au problème bien sûr :)
Cela peut être implémenté avec goto
:
for (int i = 0; i < max; i++){
Object & object1 = system.getAgent(i);
VectorOfStrings object_property1 = object1.getProperty();
for (int j = i + 1; j < max; j++){
Object & object2 = system.getObject(j);
VectorOfStrings object_property2 = object2.getProperty();
for (unsigned int k = 0; k < object_property1.size(); k++){
if (object_property1[k] == object_property2[k]){
//do something
goto cnt; //this aborts the inner most loop
//Additionally, I need the outer most loop to move on one iteration
}
}
}
cnt:;
}
C'est l'un des rares cas où l'utilisation de goto
simplifie vraiment le code.
La façon la plus lisible de résoudre ce problème classique est presque toujours de mettre les boucles imbriquées dans une fonction. Je ne sais pas ce que le code spécifique est censé faire, mais voici un pseudo-code sur lequel vous pouvez baser une solution:
bool keep_going = true;
for (int i = 0; i < max && keep_going; i++)
{
Object& object1 = system.getAgent(i);
keep_going = !compare_objects(object1.getProperty(), i+1, max);
}
où compare_objects
est quelque chose comme ceci:
inline bool compare_objects (const VectorOfStrings& obj_prop1, size_t begin, size_t end)
{
for(size_t i=begin; i<end; i++)
{
Object& obj2 = system.getObject(j);
VectorOfStrings obj_prop2 = obj2.getProperty();
for size_t j = 0; j < obj_prop1.size(); j++)
{
ifobj_prop1[j] == obj_prop2[j])
{
do_something();
return true;
}
}
}
return false;
}
Je recommande fortement l'approche de @ alexeykuzmin0, mais si vous devez travailler dans un environnement où goto
est interdit, alors l'alternative (avec un drapeau ennuyeux) est:
for (int i = 0; i < max; i++){
Object & object1 = system.getAgent(i);
VectorOfStrings object_property1 = object1.getProperty();
bool property_matched = false;
for (int j = i + 1; j < max && !property_matched; j++){
Object & object2 = system.getObject(j);
VectorOfStrings object_property2 = object2.getProperty();
for (unsigned int k = 0; k < object_property1.size(); k++){
if (object_property1[k] == object_property2[k]){
//do something
property_matched = true; // This will break the "j" loop
break; //this aborts the inner most loop
}
}
}
}
Vous pouvez utiliser lambda et utiliser return stament pour changer le contrôle. Si vous revenez vrai, le lambda se terminera et outter "pour" continuera ".
Version compacte:
for(;;) {
[&]() {
for(;;) {
if(/*break condition here*/)
return;
}
}();
}
Un modèle plus général:
for(;;) {
auto innerLoop = [&]() {
for(;;) {
if(/*break condition here*/)
return true;
}
return false;
};
if(innerLoop())
continue;
}
Pour ce cas:
for (int i = 0; i < max; i++){
Object & object1 = system.getAgent(i);
VectorOfStrings object_property1 = object1.getProperty();
auto innerLoop = [](){
for (int j = i + 1; j < max; j++){
Object & object2 = system.getObject(j);
VectorOfStrings object_property2 = object2.getProperty();
for (unsigned int k = 0; k < object_property1.size(); k++){
if (object_property1[k] == object_property2[k]){
//do something
return true;
}
}
}
return false;
};
if(innerLoop())
continue;
}