Program Tip

중첩 된 루프에서 벗어나는 방법?

programtip 2020. 9. 25. 23:30
반응형

중첩 된 루프에서 벗어나는 방법?


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

사용하다:

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

아니요, break. 이것은 마지막 남은 유효한 사용입니다 goto;)

그렇지 않은 경우 플래그를 사용하여 깊은 중첩 루프에서 벗어날 수 있습니다.

중첩 루프에서 벗어나는 또 다른 방법은 두 루프를 분리하여 별도의 함수로 분리하고 종료하려는 경우 해당 함수에서 반환하는 것입니다.

요약-중첩 된 루프에서 벗어나려면 :

  1. 사용하다 goto
  2. 플래그 사용
  3. 루프를 별도의 함수 호출로 분해

여기에 xkcd를 포함하여 저항 할 수 없었습니다. :)

여기에 이미지 설명 입력

출처

Goto's are considered harmful but as many people in the comments suggest it need not be. If used judiciously it can be a great tool. Anything used in moderation is fun.


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

One way is to put all the nested loops into a function and return from the inner most loop incase of a need to break out of all loops.

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

I think goto will solve the problem

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

end:
stmt2 

You'll need a boolean variable, if you want it readable:

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

If you want it less readable you can join the boolean evaluation:

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

As an ultimate way you can invalidate the initial loop:

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

Use this wise advice from LLVM team:

"Turn Predicate Loops into Predicate Functions"

See:

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


If you need the values of i and j, this should work but with less performance than others

for(i;i< 1000; i++){    
    for(j; j< 1000; j++){
        if(condition)
            break;
    }
    if(condition) //the same condition
        break;
}

주의 :이 답변은 정말 모호한 구조를 보여줍니다.

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

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

end:

int i = 0, j= 0;

for(i;i< 1000; i++){    
    for(j; j< 1000; j++){
        if(condition){
            i = j = 1001;
            break;
        }
    }
}

두 루프를 모두 끊습니다.


i = 0;

do
{
  for (int j = 0; j < 1000; j++) // by the way, your code uses i++ here!
  {
     if (condition)
     {
       break;
     }
  }

  ++i;

} while ((i < 1000) && !condition);

for(int i = 0; i < 1000; i++) {
    for(int j = 0; j < 1000; i++) {
       if(condition) {
          func(para1, para2...);
          return;
       }
    }
}

func(para1, para2...) {
    stmt2;
}

참고 URL : https://stackoverflow.com/questions/9695902/how-to-break-out-of-nested-loops

반응형