<문제 제시>
<문제설명>
소인수분해란 어떤 수를 소수들의 곱으로 표현하는 것입니다.
예를 들어 12를 소인수 분해하면 2 * 2 * 3 으로 나타낼 수 있습니다. 따라서 12의 소인수는 2와 3입니다.
자연수 n이 매개변수로 주어질 때 n의 소인수를 오름차순으로 담은 배열을
return하도록 solution 함수를 완성해주세요.
<예시 입출력>
<문제 해결 과정>
2, 3, 5, 7일 경우의 조건과 나눠지는 부분이 아직 남아있을 경우의 조건들을
일일이 작성해보았지만, 조건문을 만족하지 못하는 경우가 생기기도 하였고 무한루프를 돌게 되었다.
Try 1)
int[] answer = {};
List<Integer> save = new ArrayList<>();
int k = 0;
while(n > 0) {
// 낱개로 남았을때의 처리
if(n == 2 && n == 3 && n == 5 && n == 7) {
if(n == 2) {
save.add(k, 2);
k++;
}
else if(n == 3) {
save.add(k, 3);
k++;
}
else if(n == 5) {
save.add(k, 5);
k++;
}
else if(n == 7) {
save.add(k, 7);
k++;
}
}
// 더 나눌 구간이 있을경우 처리
else if(n % 2 == 0) {
save.add(k, 2);
k++;
System.out.println("n = " + n);
}
else if(n % 3 == 0) {
save.add(k, 3);
k++;
System.out.println("n = " + n);
}
else if(n % 5 == 0) {
save.add(k, 5);
k++;
System.out.println("n = " + n);
}
else if(n % 7 == 0) {
save.add(k, 7);
k++;
System.out.println("n = " + n);
}
}
System.out.println(save);
return answer;
비효율적인 코드인 것 같아, 스트림(Stream)이라는 개념을 이용해보기로 하였다.
Solution 1)
// 소수는 2부터시작하므로 2로 초기화
int i = 2;
// n이 2보다 같거나 작아질때까지 반복
while(n >= 2) {
if(n % i == 0) {
// 굳이 리스트의 인덱슬르 붙이지 않아도 값만 추가해도된다는 사실을 알게됨
save.add(i);
// n을 업데이트해줌 (i로 나눈값)
n /= i;
}
// 조건에 해당하지 않을경우 2로나누는것이아닌 i를 증가시킨 값으로 업데이트 후 나눠줌
else {
i++;
}
}
System.out.println(save);
answer = save.stream().distinct().mapToInt(Integer::intValue).toArray();
먼저 list를 사용하여 n % i == 0 처럼 조건에 일치할때마다 값을 넣어주었다.
그 결과 테스트케이스 '12' >> [2,2,3]
하지만 중복되는 값은 제거 후 배열로 반환하여야한다.
스트림은 데이터 소스마다 다른 방식으로 다루어야하는 문제점을 해결해준다.
List를 정렬할때는 Collection.sort(), 배열을 정렬할때는 Arrays.sort()를 사용하는 것을 해결한것이다.
1. stream()의 .distinct()는 스트림에서 중복된 요소를 제거한다.
2. Stream -> IntStream 변환 시, mapToInt(Integer::intValue) 사용
혹은
Stream -> IntStream 변환 시, mapToInt(Integer::parseInt) 사용
3. 이 값을 .toArray()를 통해 배열로 바꿔준다는 의미이다. (스트림을 배열로 변환)
<전체코드>
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class factorization {
public static int[] solution(int n) {
int[] answer = {};
List<Integer> save = new ArrayList<>();
// 소수는 2부터시작하므로 2로 초기화
int i = 2;
// n이 2보다 같거나 작아질때까지 반복
while(n >= 2) {
if(n % i == 0) {
// 굳이 리스트의 인덱슬르 붙이지 않아도 값만 추가해도된다는 사실을 알게됨
save.add(i);
// n을 업데이트해줌 (i로 나눈값)
n /= i;
}
// 조건에 해당하지 않을경우 2로나누는것이아닌 i를 증가시킨 값으로 업데이트 후 나눠줌
else {
i++;
}
}
System.out.println(save);
answer = save.stream().distinct().mapToInt(Integer::intValue).toArray();
return answer;
}
public static void main(String[] args) {
int n = 12;
System.out.println(Arrays.toString(solution(n)));
}
}
스트림 클래스를 응용하는 것이 어려웠지만 더 배워봐야할 부분이라고 느꼈다.
문제링크)
https://school.programmers.co.kr/learn/courses/30/lessons/120852
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
'Algorithms > 프로그래머스' 카테고리의 다른 글
[프로그래머스] '가까운 수' - Java (0) | 2023.05.11 |
---|---|
[프로그래머스] '중복된 문자 제거' - Java (0) | 2023.05.11 |
[프로그래머스] '숨어있는 숫자의 덧셈 (1)' - Java (0) | 2023.05.10 |
[프로그래머스] '문자열 정렬하기 (1)' - Java (0) | 2023.05.09 |
[프로그래머스] 'k의 개수' - Java (1) | 2023.05.09 |