Algorithm/Java
[프로그래머스/JAVA] 소수찾기
dbfl9911
2024. 9. 18. 22:08
반응형
https://school.programmers.co.kr/learn/courses/30/lessons/42839
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
- 문제 풀이
1. 숫자 조합 만드는 재귀함수 작성
public int solution(String numbers) {
// 아래 ""부분에 숫자 조합 만듬
recursive("", numbers);
}
// 중복을 제거하며 숫자 저장
HashSet<Integer> numbersSet = new HashSet<>();
public void recursive(String comb, String others) {
// comb가 비어있지 않으면 현재 조합된 숫자를 numbersSet에 추가
// 예시: comb = "12"일 때 numbersSet에 12 추가
if (!comb.equals("")) {
numbersSet.add(Integer.valueOf(comb));
}
// others 문자열에서 하나씩 문자를 선택해서 comb에 추가하고
// 남은 문자들로 새로운 조합을 재귀적으로 생성
// 예시: others = "123"일 때
// 첫 번째 반복: i = 0, comb = "1", others = "23"
// 두 번째 재귀 호출: recursive("1", "23")
for (int i = 0; i < others.length(); i++) {
// comb에 others의 i번째 문자를 추가
// others의 i번째 문자를 제외한 나머지 문자로 재귀 호출
recursive(
comb + others.charAt(i), // comb에 others의 i번째 문자를 추가
// i번째 문자를 제외한 나머지 문자열로 재귀 호출
// 예시: others = "123", i = 1일 때 others.substring(0, 1) + others.substring(2) => "13"
others.substring(0, i) + others.substring(i + 1)
);
}
}
동작 과정
- recursive("", "123")에서 시작합니다.
- 현재 comb는 빈 문자열이고, others는 "123"입니다.
- comb가 빈 문자열이므로, 아무것도 numbersSet에 추가되지 않고, others의 각 문자를 하나씩 처리하는 반복문이 시작됩니다.
첫 번째 반복 (i=0, others의 첫 번째 문자 "1"을 추가)
recursive("1", "23") 호출:
- 현재 comb = "1", others = "23".
- "1"은 비어있지 않으므로 numbersSet에 1을 추가합니다.
- 이후, others = "23"에서 다시 반복문을 돌며 숫자를 추가합니다.
두 번째 반복 (i=0, others의 첫 번째 문자 "2"을 추가):
recursive("12", "3") 호출:
- 현재 comb = "12", others = "3".
- "12"는 비어있지 않으므로 numbersSet에 12를 추가합니다.
- 이제 others = "3"에서 "3"을 추가합니다.
세 번째 반복 (i=0, others의 첫 번째 문자 "3"을 추가):
recursive("123", "") 호출:
- 현재 comb = "123", others = "".
- "123"은 비어있지 않으므로 numbersSet에 123을 추가합니다.
- 이제 others가 비어 있으므로 더 이상 재귀 호출을 하지 않고 종료합니다.
2. 소수 판별 함수 정의
// num = 29라면
// lim = (int)Math.sqrt(29)는 약 5
// i = 2: 29 % 2 ≠ 0
// i = 3: 29 % 3 ≠ 0
// i = 4: 29 % 4 ≠ 0
// i = 5: 29 % 5 ≠ 0
// 2부터 5까지의 숫자로 나누어 떨어지지 않았으므로, 29는 소수
public boolean isPrime(int num) {
// 1) 0과 1은 소수가 아님
if (num == 0 || num == 1) return false;
// 2) 제곱근까지만 확인하여 소수 여부 판단
// Math.sqrt(16) = 4
int lim = (int)Math.sqrt(num);
for (int i = 2; i <= lim; i++) {
// 나누어 떨어지면 소수가 아님
if (num % i == 0) return false;
}
return true; // 소수임
}
3. 최종 소수 개수 반환
// 최종 소수 개수 반환
public int solution(String numbers) {
// 아래 ""부분에 숫자 조합 만듬
recursive("", numbers);
// 소수 개수셈
int count = 0;
for (int number : numbersSet) {
if (isPrime(number)) {
count++;
}
}
return count;
}
- 정답 코드
import java.util.*;
class Solution {
// 숫자 조합이 들어올 hashSet(중복 제거)
HashSet<Integer> numberSet = new HashSet<>();
public void recursive(String comb, String others) {
if(!comb.isEmpty()) {
numberSet.add(Integer.valueOf(comb));
}
for(int i = 0; i < others.length(); i++) {
recursive(comb + others.charAt(i)
, others.substring(0, i) + others.substring(i+1));
}
}
public boolean isPrime(int num) {
if(num == 1 || num == 0) return false;
int lim = (int)Math.sqrt(num);
for(int i = 2; i <= lim; i++) {
if(num % i == 0) return false;
}
return true;
}
public int solution(String numbers) {
// 1. 숫자 조합 만들기 => 재귀함수 사용
recursive("", numbers);
// 2. 소수 판별하기
int count = 0;
for(int number : numberSet) {
if(isPrime(number)) {
count++;
}
}
return count;
}
}
반응형