web-dev-qa-db-ja.com

ネストされたforループでcontinueステートメントのようなものを使用するにはどうすればよいですか?

オブジェクトのクラスがあり、各オブジェクトの1つのプロパティを他のすべてのオブジェクトの同じプロパティと比較する必要があります。それらが一致する場合、コードは何かを行う必要があります。これにより、2つの「forループ」がオブジェクトをループしてそのプロパティを取得します。2番目の「forループ」では、3番目の「forループ」がプロパティの要素(ベクトル)を通過してそれらを比較します。 。それらが一致する場合、現在の反復を中止して次の反復に進むために、最も外側の「forループ」が必要です(別のオブジェクトとの最初の一致のみを考慮したい)。

「goto」ステートメントとdo {} while()構造の作成を検討しましたが、望ましい結果を得る方法でそれらを実装することができませんでした。必要なのは、最も内側のループの条件ステートメントで何が発生するかに基づいて、最も外側のループの「継続」ステートメントのようなものです。

これを達成するための良い方法はどれですか、またどのように実装する必要がありますか?

編集:私が受け入れた回答の横に、Martin Bonnerの回答もお勧めします。これも完全に正常に機能し、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
            }
        }
    }
}

したがって、「k」ループの条件ステートメントが満たされた場合、「i」ループで現在の反復を打ち切り、次の反復に移動する必要があります。

また、私は新しいので、コードは洗練されていないかもしれませんが、あなたの答えでこの特定の問題に集中してください!もちろん、コードの一般的な再構築が問題の解決策になる可能性がない限り:)

14
faranzki

これは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:;
}

これは、gotoを使用するとコードが本当に簡略化されるまれなケースの1つです。

23
alexeykuzmin0

この古典的な問題を解決する最も読みやすい方法は、ほとんどの場合、ネストされたループを関数に配置することです。特定のコードが何を行うと想定されているのかはわかりませんが、解決策の基にできるいくつかの疑似コードを次に示します。

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);
}

どこ compare_objectsは次のようなものです。

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;
}
5
Lundin

@ alexeykuzmin0のアプローチを強くお勧めしますが、gotoが禁止されている環境で作業する必要がある場合、代わりの方法(迷惑なフラグを使用)は次のとおりです。

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
            }
        }
    }
}

ラムダを使用し、リターンステートメントを使用してコントロールを変更できます。 trueを返すと、ラムダは終了し、「for」は「続行」します。

コンパクトバージョン:

for(;;) {
    [&]() {
        for(;;) {
            if(/*break condition here*/)
                return;
        }
    }();
}

より一般的なテンプレート:

for(;;) {
    auto innerLoop = [&]() {
        for(;;) {
            if(/*break condition here*/)
                return true;
        }
        return false;
    };

    if(innerLoop())
        continue;
}

この場合:

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;
}
3
Bediver