web-dev-qa-db-ja.com

ネストされたループから抜け出す方法は?

breakステートメントを使用する場合、内側のループのみが中断され、外側のループを中断するにはフラグを使用する必要があります。ただし、ネストされたループが多数ある場合、コードは適切に表示されません。

すべてのループを解除する他の方法はありますか? (goto stmtを使用しないでください。)

for(int i = 0; i < 1000; i++) {
   for(int j = 0; j < 1000; j++) {
       if(condition) {
            // both of the loops need to break and control will go to stmt2
       }
   }

}

stmt2
80
user966379

どうですか:

if(condition) {
i = j = 1000;break;
}
42
user879760

いいえ、breakで楽しさを損なわないでください。これは、gotoの最後の有効な使用です;)

そうでない場合は、フラグを使用して、深くネストされたループから抜け出すことができます。

ネストされたループから抜け出す別の方法は、両方のループを別の関数に分解し、終了したいときにその関数から戻ることです。

要約-ネストされたループから抜け出すには:

  1. gotoを使用します
  2. フラグを使用する
  3. ループを個別の関数呼び出しに分解する

ここにxkcdを含めることに抵抗できませんでした:)

enter image description here

ソース

後藤は有害とみなされます しかし、コメントの多くの人々がそうする必要はないと示唆しているように。慎重に使用すれば、すばらしいツールになります。節度に使用されるものはすべて楽しいです。

157
bool stop = false;
for (int i = 0; (i < 1000) && !stop; i++)
{
    for (int j = 0; (j < 1000) && !stop; j++)
    {
        if (condition)
            stop = true;
    }
}
34
Tung

1つの方法は、すべてのネストされたループを関数に入れ、すべてのループから抜け出す必要がある場合に最も内側のループから戻ることです。

function() 
{    
  for(int i=0; i<1000; i++)
  {
   for(int j=0; j<1000;j++)
   {
      if (condition)
        return;
   }
  }    
}
23
Jay

gotoが問題を解決すると思います

for(int i = 0; i < 1000; i++) {
    for(int j = 0; j < 1000; i++) {
        if (condition) {
            goto end;
        }
    }
}

end:
stmt2 
16
Renjith K N

可読性が必要な場合は、ブール変数が必要です。

bool broke = false;
for(int i = 0; i < 1000; i++) {
  for(int j = 0; j < 1000; i++) {
    if (condition) {
      broke = true;
      break;
    }
  }
  if (broke)
    break;
}

読みにくくしたい場合は、ブール評価に参加できます。

bool broke = false;
for(int i = 0; i < 1000 && !broke; i++) {
  for(int j = 0; j < 1000; i++) {
    if (condition) {
      broke = true;
      break;
    }
  }
}

最終的な方法として、初期ループを無効にすることができます:

for(int i = 0; i < size; i++) {
  for(int j = 0; j < 1000; i++) {
    if (condition) {
      i = size;
      break;
    }
  }
}
11
Jack

LLVMチームからのこの賢明なアドバイスを使用してください。

「述語ループを述語関数に変換する」

見る:

http://llvm.org/docs/CodingStandards.html#turn-predicate-loops-into-predicate-functions

8
ouah

Iとjの値が必要な場合、これは動作しますが、他のパフォーマンスよりもパフォーマンスが低下します。

for(i;i< 1000; i++){    
    for(j; j< 1000; j++){
        if(condition)
            break;
    }
    if(condition) //the same condition
        break;
}
4
Ali Eren Çelik

注意:この回答は、本当にあいまいな構造を示しています。

GCCを使用している場合は、 このライブラリ を確認してください。 PHPと同様に、breakは、終了するネストされたループの数を受け入れることができます。このようなものを書くことができます:

for(int i = 0; i < 1000; i++) {
   for(int j = 0; j < 1000; j++) {
       if(condition) {
            // break two nested enclosing loops
            break(2);
       }
   }
}
3
DaBler
for(int i = 0; i < 1000; i++) {
   for(int j = 0; j < 1000; i++) {
       if(condition) {
            goto end;
   }
} 

end:
2
chikuba