source

네스트 루프에서 벗어나는 방법?

goodcode 2022. 8. 3. 23:12
반응형

네스트 루프에서 벗어나는 방법?

를 사용하는 경우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

아니, 재미없게 하지 마break. 이것이 남은 유효한 마지막 사용법입니다.goto;)

그렇지 않으면 플래그를 사용하여 딥 네스트 루프에서 벗어날 수 있습니다.

네스트 루프에서 벗어나기 위한 또 다른 접근법은 두 루프를 다른 함수로 인수하여 종료할 때 해당 함수에서 복귀시키는 것입니다.

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

  1. 사용하다goto
  2. 깃발을 사용하다
  3. 루프를 인수분해 개별 함수 호출로 변환

여기에 xkcd를 포함하지 않을 수 없습니다. :)

여기에 이미지 설명 입력

원천

Goto는 해로운 것으로 간주되지만 많은 사람들이 지적하듯이 그럴 필요는 없다.신중하게 사용한다면 훌륭한 도구가 될 수 있습니다.적당히 쓰는 건 다 재밌어요.

한 가지 방법은 네스트된 모든 루프를 함수에 넣고 모든 루프를 끊어야 할 경우에 대비하여 내부 최상위 루프에서 복귀하는 것입니다.

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

읽을 수 있도록 하려면 부울 변수가 필요합니다.

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

용도:

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

생각합니다goto문제를 해결할 것이다

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

end:
stmt2 

 

LLVM 팀의 현명한 조언은 다음과 같습니다.

" 술어 루프를 술어 함수로 변환"

참조:

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

주의:이 답변은 정말로 애매한 구성을 보여준다.

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

질문은 단순히 "모든 루프를 깨는 다른 방법은 없을까?"라는 것입니다.나는 어떤 조건도 없다고 본다goto특히 OP는 좋은 방법을 요구하지 않았다.그래서 우리끼리longjmp내부 루프에서 제외되었습니까? :-)

#include <stdio.h>
#include <setjmp.h>

int main(int argc, char* argv[]) {
  int counter = 0;
  jmp_buf look_ma_no_goto;
  if (!setjmp(look_ma_no_goto)) {
    for (int i = 0; i < 1000; i++) {
      for (int j = 0; j < 1000; j++) {
        if (i == 500 && j == 500) {
          longjmp(look_ma_no_goto, 1);
        }
        counter++;
      }
    }
  }
  printf("counter=%d\n", counter);
}

setjmp함수가 두 번 반환됩니다.첫 번째로 0을 반환하고 프로그램에 의해 루프가 네스트됩니다.그럼 둘 다i그리고.jare 500, 실행한다.longjmp이 때문에,setjmp1번으로 하다

★★★★★★★★★★★★★★★★★longjmp중첩된 루프에서 벗어날 수 있습니다. 이치노

i와 j의 값이 필요한 경우, 이 값은 동작하지만 다른 값보다 성능이 떨어집니다.

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

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

func(para1, para2...) {
    stmt2;
}
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);

다른 접근법은 2개의 루프에서1개의 수동 루프로 코드를 리팩터링하는 것입니다.그러면 수동 루프의 브레이크가 외부 루프에 적용됩니다.가우스-요르단 엘리미네이션에서 이걸 사용한 적이 있는데 처리하려면 네스트 루프가 3개 필요했어요

for (int i = 0; i < 1000; i++)
{
    int j = 0;

MANUAL_LOOP:;

    if (j < 1000)
    {
       if (condition)
       {
           break;
       }

       j++;
       goto MANUAL_LOOP;
    }
}

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

반응형