Leeyanggoo
[JS] 자바스크립트 함수 문제2 / if, for, return, 연산자를 사용해 보자! 본문
마무리 문제 2. 2개의 숫자를 입력받아 두 수의 최대공약수를 구하는 함수를 작성하고 테스트해 보세요. 예를 들어 4와 12의 최대공약수는 4가 됩니다. 즉 두 수 모두 나누어떨어지는 수 중에서 가장 큰 값이 최대공약수입니다.
길라잡이
- 주어진 두 수 중에서 어떤 수가 큰 수인지 확인합니다.
- 두 수가 모두 나누어떨어져야 하므로 두 수 중에서 큰 수까지 반복하면서 작은 수도 나누어떨어지고, 큰 수도 나누어 떨어지는 숫자를 찾습니다.
- 찾을 때마다 변수에 할당합니다. 반복이 모두 끝나면 변수에는 가장 마지막에 할당된 약수만 남습니다.
function test(n1, n2){
if(n1 > n2){
return {big : n1, small : n2}
} else {
return {big : n2, small : n1}
}
}
let num1 = parseInt(prompt("첫 번째 숫자를 입력하씨오"));
let num2 = parseInt(prompt("두 번째 숫자를 입력하씨오"));
console.log(test(num1, num2));
먼저 두 수 중에 어떤 수가 큰지 알아내야 했기 때문에 이렇게 코드를 작성했다.
사실 이전에 "return big = n1" 이런 식으로 짰다가 안 돼서 내 친구 GPT 에게 물어봐서 수정했다...
function test(n1, n2){
if(n1 > n2){
return {big : n1, small : n2}
} else {
return {big: n2, small : n1}
}
for(let i = 1; i <= big; i++){
if(small % i == 0){
big % i == 0
}
console.log(`두 수의 최대공약수는 ${i}입니다.`);
}
}
let num1 = parseInt(prompt("첫 번째 숫자를 입력하씨오"));
let num2 = parseInt(prompt("두 번째 숫자를 입력하씨오"));
console.log(test(num1, num2))
두 수를 구했다면 이제 길라잡이에 따라 큰 수까지 반복해서 작은 수도 나누어떨어지고, 큰 수도 나누어떨어지는 최대공약수를 구하면 될 일이다!
...라고 생각하고 무지성으로 코드를 작성했지만 여전히 콘솔 창에는 big와 small에 할당된 숫자만 떠다녔다ㅠㅠ
이유가 뭘까 생각해 보니 return으로 반환하는 값이 두 숫자라 그런게 아닌가 하고 코드를 수정해 보았다.
function test(n1, n2){
if(n1 > n2){
let big = n1;
let small = n2;
} else {
let big = n2;
let small = n1;
} //if문이 끝나면서 변수값 사라짐...
for(let i = 1; i <= big; i++){ //big의 변수값이 없어서 for문은 성립이 안 된다..
if(small % i == 0){
big % i == 0
}
return i;
console.log(`두 수의 최대공약수는 ${i}입니다.`);
}
}
let num1 = parseInt(prompt("첫 번째 숫자를 입력하씨오"));
let num2 = parseInt(prompt("두 번째 숫자를 입력하씨오"));
console.log(test(num1, num2))
그러나 야속하게도 결과는 "Uncaught ReferenceError: big is not defined"라는 결과창만이 둥둥 떠다녔다.
왜 big 변수를 못 찾는 것일까? 이것저것 해봤지만 이유를 알 수 없던 나는 내 친구 GPT에게 물어볼 수밖에 없었다...
친구가 알려준 대답은 이렇다!
위의 코드에서는 big과 small 변수를 if문 내부에서 선언하고 있습니다. 따라서 big과 small 변수는 if문 내부에서만 사용 가능하며, if문 외부에서는 정의되어 있지 않기 때문에 for 루프에서 사용할 수 없습니다.
또한, big과 small 변수를 선언할 때 let 키워드를 사용하면, 해당 변수는 if문 블록 내부에서만 유효한 지역 변수로 선언됩니다. 이렇게 되면 if문 외부에서는 변수가 정의되어 있지 않으므로, for 루프에서 사용할 수 없습니다.
그렇다. 내가 if문에서 구한 'big'와 'small' 변수는 if문의 종료와 함께 저멀리 날아간 것이었따...
즉 'big'와 'small' 변수가 for문의 루프에서 사용되기 위해선 변수의 선언을 if문 외부에서 해야 했다.
또한 for문에서 최대공약수 i를 구하는 방법 역시 더 보기 좋게 논리 연산자를 사용하는 방법도 있었다.
내가 구하려는 최대공약수는 최댓값인 big와 최솟값인 small이 나눠지는 수였기 때문에 조건이 true and true인 "&&"로 좀 더 효율적으로 표현할 수 있었다.
function test(n1, n2){
let big, small; //외부에 변수를 선언
if(n1 > n2){
big = n1;
small = n2;
} else {
big = n2;
small = n1; //변수에 값 넣기
}
let result; //외부에 변수를 선언
for(let i = 1; i <= big; i++){
if(small % i === 0 && big % i === 0){
result = i; //변수에 for문이 끝날 때까지 값을 저장
}
}
return result; //for문 바깥에 return을 사용하여 최종 결과 반환
}
let num1 = parseInt(prompt("첫 번째 숫자를 입력하시오."));
let num2 = parseInt(prompt("두 번째 숫자를 입력하시오."));
console.log(`두 숫자의 최대공약수는 ${test(num1, num2)}이올시다.`);
이렇게 최대공약수를 구하기 위한 여정은 끝이 났다.
하지만 답지를 보니 훨씬 더 간결하게 최대공약수를 구하고 있었다...
함수를 간략히 표현하는 데 있어서 여러 연산자가 중요하는 점을 알 수 있었다.
// 최대공약수 : Greatest Common Divisor (GCD)
function getGCD(n, m) {
let max = n > m ? n : m;
let GCD = 0;
for (let i = 1; i <= max; i++) {
if (n % i === 0 && m % i === 0) {
GCD = i; // 최대공약수
}
}
return GCD;
}
console.log(`308과 20의 최대공약수 : ${getGCD(308, 20)}`);
console.log(`45과 38의 최대공약수 : ${getGCD(45, 38)}`);