【问题标题】:How to stop a nested for loop如何停止嵌套的for循环
【发布时间】:2013-10-14 15:44:07
【问题描述】:

我希望在找到一个在 x 中具有相同位置的对象后立即停止两个循环。

这是我的 C++ 代码:

for(int i = 0; i < sizeArray; ++i){
    for(int j = i; j > 0; --j){
        if (s[i].positionX == s[j-1].positionX){
            s[i].positionY = s[j-1].positionY; 
        }
    }
}

如果我使用break;,它只会跳出内部 for 循环。阻止两者的最佳方法是什么?

选项:

  1. 将循环的索引设置为最大值(或最小值)以终止循环。
  2. 将所有这些放在一个函数中并使用 return。
  3. 使用转到
  4. 使用 Lambda
  5. 将布尔停止代码设置为 true、break,然后监听 break 并跳出其他循环?
  6. ?

【问题讨论】:

  • while 语句(例如 while x != y)能解决您的问题吗?
  • 休息;可以解决问题
  • 我已经在 if 语句中尝试过 break 但它不起作用。
  • 由于内部循环中没有使用j,因此内部循环唯一要做的就是在i 为零时跳过if 语句。你的代码正确吗?也许您打算在当前有i-1 的地方使用j
  • 是的,抱歉。它应该是 s[j-1].positionX 和 s[j-1].positionY

标签: c++ loops for-loop if-statement


【解决方案1】:

要跳出最里面的for 循环,请使用break

要突破最外层,要么使用goto,要么使用break 和“应该停止”标志的组合。

【讨论】:

【解决方案2】:

我建议使用 lambda:

auto do_work = [&] {
   for(int i = 0; i < sizeArray; ++i){
       for(int j = i; j > 0; --j){
           if (s[i].positionX == s[i-1].positionX){
               s[i].positionY = s[i-1].positionY; 
               return;
           }
       }
   }
};

do_work();  //you can call this multiple times if you need to!

没有break,没有goto。 :-)

在这种情况下,它的用途与breakgoto 相同,但该技术似乎很干净,至少对我而言。此外,一旦您拥有带有名称名称)的 lambda,如果需要,您可以多次使用它——因此这种技术提高了代码的可读性并鼓励代码重用。

当然,如果您不需要多次调用它,那么您可能不需要名称。你可以这样做:

[&]
{
   //your code with the added return statement.
}();

但正如我所说,name 提高了可读性,即使您不多次调用它。


如果由于某种原因您不能使用 lambda,那么您仍然可以避免使用额外的变量,例如 stop 以及涉及它的额外工作(正如 @ssantos 的回答所建议的那样):

for(int i = 0; i < sizeArray; ++i){
    for(int j = i; j > 0; --j){
        if (s[i].positionX == s[i-1].positionX){
            s[i].positionY = s[i-1].positionY; 
            i = sizeArray; //it will break the outer loop!
            break;
        }
    }
}

希望对您有所帮助。

【讨论】:

  • 虽然您在建议 break 的替代方案,但 throw/catch (ducks) 怎么样。 (+1)
  • 但是return; 的用途与breakgoto 完全相同。
  • 其实他甚至都不需要存储。 (([](){})()) - 也就是说,假设他只想调用一次。
  • @glglgl:它具有相同的目的,但似乎很干净,至少对我来说是这样。此外,一旦您拥有带有 a name 的 lambda(一个不错的名称),如果需要,您可以多次使用它。这是一种具有其他用法的技术,这是 breakgoto 无法实现的,同时保持代码整洁。
【解决方案3】:

我猜你要求停止 for 循环。您要查找的关键字是break。但是,如果您想退出两个 for 循环,则需要在代码中添加一个变量。-

bool stop = false;

for(int i = 0; i < sizeArray; ++i){
    for(int j = i; j > 0; --j){
        if (s[i].positionX == s[i-1].positionX){
            s[i].positionY = s[i-1].positionY; 
            stop = true;
            break;
        }
    }
    if (stop) {
        break;
    }
}

【讨论】:

    【解决方案4】:

    把你贴出来的代码放到自己的函数里,赋值后把return放到里面。

    【讨论】:

      【解决方案5】:

      您可以使用break 停止for 循环。

      使用嵌套的for 循环,事情就不那么容易了。你可以实现你的目标

      • 设置标志(done = 1; 并与for(int j = i; j &gt; 0 &amp;&amp; !done; --j) 一起使用)
      • goto。尽管goto 不被某些人所接受,但如果使用得当并小心谨慎,它可以成为解决某些问题的合法解决方案,例如错误处理,或者一般来说,“完成处理”。

      【讨论】:

        【解决方案6】:

        试试下面的

        bool match = false; 
        
        for(int i = 0; i < sizeArray && !match; ++i){
            for(int j = i; j > 0 && !match; --j){
                if ( match = ( s[i].positionX == s[i-1].positionX ) ){
                    s[i].positionY = s[i-1].positionY; 
                }
            }
        }
        

        另一种方式如下

         for(int i = 0; i < sizeArray; ++i){
              int j = i;
              while ( j != 0 && s[i].positionX != s[i-1].positionX ) --j;
              if ( j != 0 ) {
                   s[i].positionY = s[i-1].positionY; 
                   break; 
              }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-11
          • 2020-01-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多