이번 시간에는 제가 모 사이트에서 4200문제를 풀면서 매우 뜸하게 썼던 반복문인 c언어 do while문을 알아보도록 하겠습니다. 구현 문제에서 가끔 썼던 것 말고는 for나 while보다는 매우 많이 빈도가 적었습니다. 저 둘은 아마 제가 그 사이트에서 낸 코드들을 보면, 각각 10만 ~ 13만회 정도, 혹은 그 이상도 썼을 듯 싶은데, 오늘 배울 반복문은 많아봤자 90회 정도 썼을 거에요. 그 정도로 빈도가 매우 적습니다. 90회 vs 10만회. 비교가 안 될 정도의 빈도입니다.

 

 

do{block}while(cond1);

 

 

 문법은 대략 이러합니다. do를 먼저 써 주고 반복문 블록이 온 다음에, while이 옵니다. 그 안에 cond1, 즉, 조건이 들어갑니다. 예를 들어서 T>0이냐? 등등이 말입니다. 중요한 것은 맨 뒤에 세미콜론이 붙는다는 겁니다.

 

 

 실행 흐름도는 다음과 같습니다. 반복문 블록 안에 있는 문장은 최소 1번 이상 수행되는 게 보장됩니다. 이것이 for문과 while문과의 차이점이라고 봐도 무난할 듯 싶어요.

 

 


 예제 1번 프로그램을 봅시다. 저번에 while문을 배웠으니까, 실행 흐름도는 그리실 수 있을 거에요. 어떻게 그려질까요? 일단 블록 안에 print와, T를 하나 감소시키는 문장이 있습니다.

 

 

 그러면 대략적으로 이런 식으로 그려지겠어요. 처음에 T는 5로 초기화가 되어 있고, 5일 때 조건 만족하니까, 5 출력하고 T 값이 하나 줄어듭니다. 이렇게 계속 T가 1씩 줄어들다가, 언제 끝나나요? T가 0이 될 때 T>0이 아니기 때문에, 빠져 나오겠네요.

 

 

 그러면 5, 4, 3, 2, 1 순서대로 출력이 되고 끝날 거에요.

 

 

 이 경우는 어떨까요? 마찬가지로 어떻게 흘러가는지 흐름도를 그려봅시다.

 

 

 보시면 일단, 반복문을 돌기 위한 조건문이 맨 아래에 왔음을 볼 수 있어요. 이게 차이점이라면 차이점일 건데, T값이 5라면 사실 출력 결과는 똑같을 겁니다. 왜냐하면, T가 5일 때, 5를 출력하고, T가 4가 될 겁니다. 그리고 이 때, T>0이냐를 검사합니다.

 

 이런 루틴으로 계속 따라가다 보면 T가 1일 때, 1을 출력하고, T를 하나 감소시킬 겁니다. 그리고 T>0인지 검사하는데, 이 때, T가 0이므로 1까지 출력하고 나오게 될 거에요.

 

 

 그런데, T값이 0인 경우 이야기가 달라집니다. 단순히 while(T>0){...} 이였다면, 0>0이 거짓이기 때문에, 블록 안에 있는 문장들이 수행되지 않을 것입니다. 그런데 이 경우 이야기가 달라집니다.

 

 

 T가 어떤 값이던지간에, 먼저 초록색 부분이 실행됩니다. 그러면 T값이 출력이 될 거에요. 0이 출력되겠네요. 다음에 하나 감소하는데요. 이 때 -1>0은 거짓이므로 빠져나오게 됩니다. 루프 안의 문장들이 최소 1번 이상 수행된다는 차이가 잘 드러나는 예제라고 할 수 있습니다.

 

 


 보통, 구현 문제에서 조합 문제를 많이 만나는 경우가 있습니다. 순열이나. 코딩 테스트에서 많이 좋아하는 유형 중 하나입니다. 그러한 경우 next_permutation 함수의 사용이 생각보다 잦은데요. 순열을 출력하는 경우, 이 함수와 궁합이 매우 잘 맞기 때문입니다.

 

 이 때, do while문하고 같이 쓰는데요. 이는 요 함수의 특성 때문입니다. 먼저 next_permutation은 다음 순열이 존재한다면, 현재 순열을 다음 순열로 바꿔버립니다. 그렇지 않다면 false를 리턴합니다.

 

 

 그러면 처음에 {0,1,2,3}이였고, next_perm... 리턴값을 while문으로 주었을 때, 0 1 2 3의 다음 것이 있을 겁니다. 0 1 3 2입니다. 그런가요? 그렇기 때문에, 순열이 0 1 3 2로 바뀝니다.

 

 

 그러면 이 프로그램의 수행 결과는 어떻게 나올까요? 일단, perm이 3 2 0 1이였다고 해 봅시다. 다음 순열이 있기 때문에, while에 걸려있는 함수에 의해서, 3 2 1 0이 되면, while 안에 있는 블록이 수행되는데요. 이 때 3 2 1 0이 출력됩니다. 그리고 나서, 3 2 1 0의 다음 것은 없으니까 빠져나올 겁니다.

 

 그러면 3 2 1 0까지 출력이 될 겁니다. 0 1 2 3은 print가 될까요? 아닙니다. 다음 원소가 있기 때문에, 0 1 2 3이 아닌, 그것의 next인, 0 1 3 2부터 출력이 될 겁니다.

 

 

 따라서 4!-1개의 순열이 출력됩니다.

 

 

 하지만 이 경우에는 이야기가 다릅니다. 0 1 2 3 이 들어왔다고 한다면, 그 순열을 먼저 출력합니다. 그리고 다음 것이 있는지 검사하고 있다면 바꿉니다. 그러면 0 1 3 2 로 바뀔 겁니다. 3 2 0 1을 출력했다고 해 봅시다. 이것의 다음 것은 3 2 1 0으로 있기 때문에, 12번째 줄을 다 수행하고 나면, 순열이 3 2 1 0으로 바뀝니다.

 

 그러면 3 2 1 0까지 출력이 될 겁니다. 다음에 12번째에 걸린 조건을 검사하니까 3 2 1 0이 마지막이네요. 빠져 나오게 됩니다. 따라서, 모든 permutation이 출력되게 됩니다.

 

 

 0 1 2 3도 출력이 된다 정도 이해하시면 좋겠습니다. 이 덕분에 조합이라던지 순열과 시뮬레이션이 나오면, do while을 쓰는 빈도가 많아집니다. 제가 백준에서 문제를 풀면서, 90개 정도의 문제의 반복문을 썼다고 했었는데요. 그 중 80% 이상이 저 패턴이였어요. 딱 봐도 perm이 나와야 할 거 같고. 그걸 토대로 시뮬레이션 돌리는 문제들이 몇 개 있는데요. 그러한 문제들에서 많이 썼습니다.