如何打破嵌套循环?

use*_*379 81 c break nested-loops

如果我使用一个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
Run Code Online (Sandbox Code Playgroud)

Sri*_*aju 165

不,不要破坏乐趣break.这是最后剩余的有效使用goto;)

如果不是这样,那么你可以使用标志来打破深嵌套循环.

打破嵌套循环的另一种方法是将两个循环分解为单独的函数,并在要退出时从该函数返回.

总结 - 打破嵌套循环:

  1. 使用 goto
  2. 使用标志
  3. 将循环分解为单独的函数调用

忍不住在这里包括xkcd :)

在此输入图像描述

资源

Goto被认为是有害的,但评论中的许多人认为它不一定是有害的.如果明智地使用它可以是一个很好的工具.适度使用的任何东西都很有趣.

  • Goto和你在这里一样清楚,是的.将退出变量设置为1000甚至更加笨拙. (25认同)
  • 我想补充一点,那些不是明确的邪恶,它们只是用于邪恶.我发现有很多情况,例如这个,它们是最好的解决方案."不要使用gotos"是一个好的开始,但我认为技能的下一步允许你"不要使用远程的getos". (3认同)
  • 到目前为止+1的最短摘要. (2认同)
  • +1。Donald E. Knuth 的 Structured Programming with go to Statements (http://wiki.c2.com/?StructuredProgrammingWithGoToStatements) 是一篇平衡 Dijkstra 的有趣文章。 (2认同)

小智 41

关于什么:

if (condition) {
    i = j = 1000;
    break;
}
Run Code Online (Sandbox Code Playgroud)

  • 工作,但丑陋而不是一般.如果有人将限制更改为2000(假设代码更长,所以你没有立即注意到它)怎么办? (43认同)
  • 正如@ugoren指出的那样,这不是一般解决方案.由于这是此问题的第一个Google热门话题,如果选择了常规解决方案,那就太好了.好吧人们习惯于检查#2. (4认同)
  • @ugoren 那也很简单。如果您在全局初始化中使用“const int count =1000”会怎样?或作为“#define”宏。 (2认同)

Tun*_*ung 34

bool stop = false;
for (int i = 0; (i < 1000) && !stop; i++)
{
    for (int j = 0; (j < 1000) && !stop; j++)
    {
        if (condition)
            stop = true;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 可以设置"stop = true;" 然后"休息".然后,在内部"for"循环结束后,执行"if(stop)break;". (4认同)
  • 我认为这是最优雅的非“goto”解决方案。它不需要知道条件内“i”和“j”的限制。我喜欢将 `if (stop) break;` 放在内部循环之后的想法,它本身可以在设置 `stop` 后 `break`。 (4认同)

Jay*_*Jay 23

一种方法是将所有嵌套循环放入一个函数中,并从最内层循环返回,需要打破所有循环.

function() 
{    
  for(int i=0; i<1000; i++)
  {
   for(int j=0; j<1000;j++)
   {
      if (condition)
        return;
   }
  }    
}
Run Code Online (Sandbox Code Playgroud)


Ren*_*K N 16

我认为goto会解决问题

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

end:
stmt2 
Run Code Online (Sandbox Code Playgroud)


Jac*_*ack 12

如果你想要它可读,你需要一个布尔变量:

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;
}
Run Code Online (Sandbox Code Playgroud)

如果您希望它具有较低的可读性,您可以加入布尔评估:

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

作为一种终极方式,您可以使初始循环无效:

for(int i = 0; i < size; i++) {
  for(int j = 0; j < 1000; i++) {
    if (condition) {
      i = size;
      break;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)


oua*_*uah 9

使用LLVM团队的这个明智的建议:

"将谓词循环转换为谓词函数"

看到:

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


DaB*_*ler 6

注意:这个答案显示了一个真正晦涩的结构。

如果您使用 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);
       }
   }
}
Run Code Online (Sandbox Code Playgroud)

  • 在幕后,它确实是[使用`goto`](https://github.com/xbarin02/c-ext/blob/master/include/break#L35):) (3认同)