while 과 for 반복문 실습 과제

while 과 for 반복문 실습 과제

2021.11.17 - [Language/JavaScript] - while 과 for 반복문

반복문의 마지막 값

아래 코드를 실행했을 때 얼럿 창에 마지막으로 뜨는 값은 무엇일까요? 이유도 함께 설명해보세요.

let i = 3; while (i) { alert( i-- ); }

풀이

let i = 3; while (i) { alert( i-- ); } /* (1) i = 3 : alert(3)이 실행되고 i는 2가 된다. (2) i = 2 : alert(2)가 실행되고 i는 1이 된다. (3) i = 1 : alert(1)이 실행되고 i는 0이 된다. --> 마지막 출력값 (4) 0 은 falsy 값이므로 반복문이 종료된다. */

해설

답: 1

반복이 하나씩 끝날 때마다 i는 1씩 줄어듭니다. while(i)은 i = 0일 때 멈춥니다.

따라서 전체 반복문은 아래 순서를 따라 실행됩니다.

let i = 3; alert(i--); // 3이 출력되고 i는 2로 줄어듭니다. alert(i--) // 2가 출력되고 i는 1로 줄어듭니다. alert(i--) // 1이 출력되고 i는 0으로 줄어듭니다. // i가 0이 되었기 때문에 while(i)는 종료됩니다.

while 반복문의 출력값 예상하기

while 반복문이 순차적으로 실행될 때마다 얼럿 창에 어떤 값이 출력될지 예상해보세요.

아래 두 예시는 같은 값을 출력할까요?

전위형 증가 연산자를 사용한 경우(++i):

let i = 0; while (++i < 5) alert( i );

후위형 증가 연산자를 사용한 경우(i++):

let i = 0; while (i++ < 5) alert( i );

풀이

전위형 증가 연산자를 사용한 경우(++i):

let i = 0; while (++i < 5) alert( i ); /* 1) 1 < 5 가 true 이므로 alert(1)이 실행된다 2) 2 < 5 가 true 이므로 alert(2)가 실행된다 ... 4) 4 < 5 가 true 이므로 alert(4)가 실행된다. 5) 5 < 5 가 false 이므로 반복문이 종료된다. 출력값 : 1, 2, 3, 4 */

후위형 증가 연산자를 사용한 경우(i++):

let i = 0; while (i++ < 5) alert( i ); /* i = 0 일때 0 < 5 는 true 이므로 alert()이 실행된다. 이때 i = 1이다 i = 1 일때 1 < 5 는 true 이므로 alert()이 실행된다. 이때 i = 2이다 ... i = 4 일때 4 < 5 는 true 이므로 alert()이 실행된다. 이때 i = 5이다 i = 5 일때 5 < 5 는 false 이므로 반복문이 종료된다 출력값 : 1, 2, 3, 4, 5 */

해설

이 문제는 비교 연산자와 후위/전위형 연산자를 함께 사용하는 경우 어떤 차이가 있는지 보여줍니다.

전위형 증가 연산자를 사용한 경우엔 1부터 4까지 출력됩니다.

++i는 i를 먼저 증가시키고 새로운 값을 반환하기 때문에 첫 번째 while 반복문에선 1과 5를 비교(1 < 5)하고, 얼럿 창엔 1이 출력됩니다.

1에 이어서 2, 3, 4…이 출력됩니다. i 앞에 ++가 붙어있기 때문에 5는 항상 증가 이후의 값과 비교됩니다.

i = 4 이후에 i의 값이 5로 증가하면 while(5 < 5)안의 비교가 실패하기 때문에 반복문은 멈춥니다. 따라서 5는 출력되지 않습니다.

후위형 증가 연산자를 사용한 경우엔 1부터 5까지 출력됩니다.

후위 증가 연산자를 적용하면 i++는 i를 증가시키긴 하지만 기존 값을 반환합니다. 따라서 첫 번째 while 반복문에선 0과 5를 비교(0 < 5)합니다. 이 점이 전위 증가 연산자와의 차이입니다.

그런데 alert문은 조건문과 별개의 문이므로 얼럿창엔 1이 출력됩니다. i는 이미 증가한 이후이기 때문이죠.

1이 출력된 이후에 2, 3, 4…가 이어서 출력됩니다.

i = 4일 때 잠시 생각을 가다듬어 봅시다. 전위 증가 연산자(++i)를 사용하면 값이 먼저 증가하기 때문에 5와 5를 비교하게 되는데, 여기선 후위 증가 연산자(i++)를 사용하고 있으므로 i는 증가하지만 기존 값인 4가 비교에 사용됩니다. 따라서 while(4 < 5)가 되고, 해당 조건은 참이므로 하단 블록이 실행되어 alert 창이 뜨게 됩니다.

다음 반복문은 while(5 < 5)이므로 마지막 출력되는 값은 5가 됩니다.

'for' 반복문의 출력값 예상하기

for 반복문이 순차적으로 실행될 때마다 얼럿 창에 어떤 값이 출력될지 예상해보세요.

아래 두 예시는 같은 값을 출력할까요?

후위형 증가 연산자를 사용한 경우(i++):

for (let i = 0; i < 5; i++) alert( i );

전위형 증가 연산자를 사용한 경우(++i):

for (let i = 0; i < 5; ++i) alert( i );

풀이

후위형 증가 연산자를 사용한 경우(i++):

for (let i = 0; i < 5; i++) alert( i ); /* i = 0 > alert (0) i = 1 > alert (1) i = 2 > alert (2) i = 3 > alert (3) i = 4 > alert (4) i = 5 > false 출력값: 0, 1, 2, 3, 4 */

전위형 증가 연산자를 사용한 경우(++i):

for (let i = 0; i < 5; ++i) alert( i ); /* i = 0 > alert(0) --> 먼저 실행됨 i = 1 > alert(1) i = 2 > alert(2) i = 3 > alert(3) i = 4 > alert(4) i = 5 > false 출력값 : 0, 1, 2, 3, 4 ㄴ for 반복문은 본문이 실행되고 나서 i가 증가하기 때문에 후위형 증가 연산자와 차이가 없다 */

해설

두 경우 모두 0부터 4까지 출력됩니다.

for (let i = 0; i < 5; ++i) alert( i ); for (let i = 0; i < 5; i++) alert( i );

for문의 알고리즘을 떠올려보면 쉽게 추론할 수 있는 문제입니다.

모든 작업이 시작되기 전 일단 i = 0입니다. i < 5 조건을 만족하는지 확인합니다. 위 조건이 true이면 반복문의 본문 alert(i)가 실행되고, 그 이후 i++가 실행됩니다.

i++는 위 알고리즘의 두 번째 단계(조건 확인)와 별개로 실행됩니다. 전혀 다른 구문이기 때문이죠.

증가 연산자가 반환하는 값은 (2) 에서 쓰이지 않기 때문에 i++와 ++i에 차이가 없습니다.

for 반복문을 이용하여 짝수 출력하기

for 반복문을 이용하여 2부터 10까지 숫자 중 짝수만을 출력해보세요.

풀이

for(let i = 1; i <= 10; i++) { if (i % 2 != 0) continue; alert(i); } // =============================== for(let i = 1; i <= 10; i++) { if (i % 2 == 0) { alert(i); } }

해설

for (let i = 2; i <= 10; i++) { if (i % 2 == 0) { alert( i ); } }

나머지 연산자 %를 사용하면 짝수인지를 확인할 수 있습니다.

'for 반복문을 'while' 반복문으로 바꾸기

for 반복문을 while 반복문으로 바꾸되, 동작 방식에는 변화가 없도록 해보세요. 출력 결과도 동일해야 합니다.

for (let i = 0; i < 3; i++) { alert( `number ${i}!` ); }

풀이

let i = 0; while (i < 3) { alert(`number ${i}!`); i++ }

해설

let i = 0; while (i < 3) { alert( `number ${i}!` ); i++; }

사용자가 유효한 값을 입력할 때 까지 프롬프트 창 띄우기

사용자가 100보다 큰 숫자를 입력하도록 안내하는 프롬프트 창을 띄워보세요. 사용자가 조건에 맞지 않은 값을 입력한 경우 반복문을 사용해 동일한 프롬프트 창을 띄워줍시다.

사용자가 100을 초과하는 숫자를 입력하거나 취소 버튼을 누른 경우, 혹은 아무것도 입력하지 않고 확인 버튼을 누른 경우엔 더는 프롬프트 창을 띄워주지 않아도 됩니다.

사용자가 오직 숫자만 입력한다고 가정하고 답안을 작성하도록 해봅시다. 숫자가 아닌 값이 입력되는 예외 상황은 처리하지 않아도 됩니다.

풀이

let num = +prompt('100보다 큰 숫자를 입력하세요',''); while(true) { if(num <= 100) { num = +prompt('100보다 큰 숫자를 입력하세요',''); } else if (num == '' || num == null) { break; } }

해설

let num; do { num = prompt("100을 초과하는 숫자를 입력해주세요.", 0); } while (num <= 100 && num);

do..while반복문을 사용해 아래 두 조건이 모두 truthy인 경우 프롬프트 창이 뜨게 하면 됩니다.

num <= 100인지 확인하기. 100보다 작거나 같은 값을 입력한 경우 프롬프트 창이 떠야 합니다. num이 null이나 빈 문자열인지 확인하기.

num이 null이나 빈 문자열이면 && num이 거짓이 되므로 while 반복문이 종료됩니다.

참고: num이 null인 경우 num <= 100은 true가 되므로 두 번째 조건이 없으면 취소 버튼을 눌러도 반복문이 계속해서 실행됩니다. 따라서 위 두 조건을 모두 확인해야 합니다.

소수 출력하기

소수(prime number)는 자신보다 작은 두 개의 자연수를 곱하여 만들 수 없는 1보다 큰 자연수입니다.

다시 말해서 1과 그 수 자신 이외의 자연수로는 나눌 수 없는 자연수를 소수라고 부르죠.

5는 2나 3, 4로 나눌 수 없기 때문에 소수입니다. 5를 이들 숫자로 나누면 나머지가 있기 때문이죠.

2부터 n까지의 숫자 중 소수만 출력해주는 코드를 작성해봅시다.

n = 10이라면 결과는 2,3,5,7이 되어야겠죠.

주의: 작성한 코드는 임의의 숫자 n에 대해 동작해야 합니다.

풀이

let num = +prompt('숫자') primeNum: for(let i = 2; i < num; i++) { for(let j = 2; j < i; j++) { if( i % j == 0) { continue primeNum; } } alert(i); }

해설

소수를 판단하는 알고리즘은 다양합니다.

먼저 중첩 반복문을 사용한 알고리즘을 살펴봅시다.

범위 내 모든 숫자 i에 대해서 { 1과 i 사이에 제수가 있는지를 확인 있으면 => 소수가 아님 없으면 => 소수이므로 출력해줌 }

레이블을 사용해 위 알고리즘을 구현한 코드는 다음과 같습니다.

let n = 10; nextPrime: for (let i = 2; i <= n; i++) { // 각 i에 대하여 반복문을 돌림 for (let j = 2; j < i; j++) { // 제수(나눗수)를 찾음 if (i % j == 0) continue nextPrime; // 소수가 아니므로 다음 i로 넘어감 } alert( i ); // 소수 }

위에서 사용한 알고리즘은 최적화할 부분이 많습니다. 제수를 2와 i의 제곱근 사이에서 찾으면 좀 더 나아지겠죠. 아주 큰 n에 대해서 이차 체(Quadratic sieve)나 수 체(General number field sieve)와 같이 좀 더 어려운 수학과 복잡한 알고리즘을 이용해 소수 검색 알고리즘을 개선할 수 있을 겁니다.

from http://heimish-web.tistory.com/57 by ccl(A) rewrite - 2021-11-17 17:02:04