데일리 코딩을 하면서 풀었던 문제인데 수를 입력받아 2의 거듭제곱인지 확인하는 코드를 짜는 것이었다.
내가 생각한 방식과 레퍼런스 코드의 풀이 방법이 달라서 기록하려고 한다.
문제
수를 입력받아 2의 거듭제곱인지 여부를 리턴한다.
입력
인자 1 : num
int 타입의 정수 (num >= 1)
출력
boolean 타입
주의 사항
• while문을 사용해야 한다.
• Math.log 사용은 금지된다.
입출력 예시
boolean output1 = powerOfTwo(128);
System.out.println(output1); // true
boolean output2 = powerOfTwo(34);
System.out.println(output2); // false
2의 거듭제곱이란 2를 n번 곱한 수이기 때문에 반대로 생각해서 수를 2로 계속 나눠서 나머지가 0인지 알아내면 된다고 생각했다.
public boolean powerOfTwo(long num) {
// while문으로 반복(2 초과일때만) -> 1, 2는 거듭제곱이 맞으니까
// num을 2로 나머지 연산했을 때 0이 나오지 않으면 false 리턴
// num을 2로 나눠서 num값에 대입해준다.
// while문을 벗어나면 true 리턴
}
의사 코드를 먼저 작성을 했다.
while문 조건 설정할 때 중요한 점은 입력받을 num의 범위가 1 이상의 값이라는 것이다.
어렵지 않은 내용이어서 바로 코드로 옮겨서 작성하였다.
public boolean powerOfTwo(long num) {
while(num > 2){ // while문으로 반복(2 초과일때만) -> 1, 2는 거듭제곱이 맞으니까
if(num % 2 == 1) return false; // num / 2 가 딱 나누어 떨어지지 않으면 false 리턴
num /= 2; // num을 2로 나눠서 num값에 대입해준다.
}
// while문을 벗어나면 true 리턴
return true;
}
다행히 테스트는 틀린부분 없이 통과했다.
레퍼런스 코드도 한번 살펴보았다.
public boolean powerOfTwo(long num) {
if (num == 1) { // 입력받은 수가 1이면 true 리턴
return true;
}
if (num % 2 != 0) { // 입력받은 수가 홀수이면 false 리턴
return false;
}
long powered = 2; // 정수 2를 값으로 하는 변수를 만듦
while (powered < num) { // 변수 powered가 입력받은 num 값 이상이 될 때까지 2를 곱함
powered = powered * 2;
}
return powered == num; // num이 2의 거듭제곱인 powered와 같다면 true 아니면 false 리턴
}
주석은 내가 이해한대로 달았다.
나는 num을 2로 나누는 방식으로 코드를 짰다면
위 코드는 num 값 이상인 2의 거듭제곱 중 가장 작은 값을 갖는 변수를 만들어 num이 그 값과 같은지를 비교한다.
"return a == b"라는 방식이 아직은 좀 생소하다. 코드를 봤을 때 이해가 바로 가는데, 막상 코드 작성 시에는 까먹는 방법이다.
진짜 코드 짜는 법에는 정해진 길이 없는 것 같다.
그렇기에 내가 풀었던 문제라도 레퍼런스 코드를 한번씩 보면서 사고의 폭을 넓히는 게 좋을 것 같다.
문제가 쉬워서 그럴지는 몰라도 아직은 문제 푸는게 즐겁다.
슨배임들 조언 환영합니다.
'Codestates > Java' 카테고리의 다른 글
자바 유클리드 호제법으로 최대공약수 구하기 (0) | 2022.11.28 |
---|---|
자바 재귀 함수를 이용하여 짝수, 홀수 구분하기 (0) | 2022.11.17 |