[Java] 프로그래머스 - Java 기초
[Java] 프로그래머스 Java 기초 문제 풀이 과정을 정리한 글입니다.
For the English version of this post, see here.
몫 구하기
https://school.programmers.co.kr/learn/courses/30/lessons/120805
Java에서 몫을 구하기 위해서는 /를 사용해야한다.
정수 / 정수 → 정수값 몫을 반환하는데
실수 / 정수 → 와 같이 하나라도 실수라면 실수값 몫을 제공한다.
Java에서 //기호는 주석을 의미하기 때문에 Python에서와 같이 //로 몫을 구할 수 없다.
분수의 덧셈
https://school.programmers.co.kr/learn/courses/30/lessons/120808
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public int[] solution(int numer1, int denom1, int numer2, int denom2) {
int[] answer = new int[2];
answer[0] = numer1*denom2 + numer2*denom1;
answer[1] = denom1 * denom2;
while(answer[0] != 1) {
for(int i = answer[1]; i>=1; i--) {
if (answer[0] % i == 0 && answer[1] % i == 0) {
answer[0] /= i;
answer[1] /= i;
}
}
}
return answer;
}
}
- 처음 코드의 오류
- 기약 분수가 된다고 해서, 분자가 다 1이 되는 것은 아니다.
- 분자가 1이 아니라도 기약 분수가 되면 반복을 종료하도록 해야한다.
약분하려면 분자와 분모 중 더 작은 값을 찾는 것이 우선이다.
- 또한, 분모 수에서 1까지 반복하는 for문에서 1은 약분에서 의미가 없으므로 확인할 필요가 없다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
class Solution { public int[] solution(int numer1, int denom1, int numer2, int denom2) { int[] answer = new int[2]; answer[0] = numer1*denom2 + numer2*denom1; answer[1] = denom1 * denom2; for(int i = Math.min(answer[0], answer[1]); i>=2; i--) { if (answer[0] % i == 0 && answer[1] % i == 0) { answer[0] /= i; answer[1] /= i; break; } } return answer; } }
- 기약 분수가 된다고 해서, 분자가 다 1이 되는 것은 아니다.
- 수정 후 코드
최대공약수로 한 번만 나누면 기약분수가 됨 →
while문이 필요 없다.Math.min()을 사용 → 분자와 분모 중 작은 값 반환
중앙값 구하기
https://school.programmers.co.kr/learn/courses/30/lessons/120811
Java에서의 배열
배열 선언
1
int[] arr;
배열 생성
1
int[] arr = new int[5];
배열 선언과 동시에 초기화
1
int[] arr = {10, 20. 30, 40, 50};
배열 길이 확인
1 2
len = arr.length; System.out.println(arr.length);
배열 정렬
Arrays.sort()메서드 사용1 2 3 4 5 6 7 8
import java.util.Arrays; int[] arr = {5, 2, 8, 1, 3}; Arrays.sort(arr); System.out.println(Arrays.toString(arr)); // [1, 2, 3, 5, 8]
Arrays.sort(arr);→ 배열을 오름차순으로 정렬Arrays.toString(arr)→ 배열의 요소를 문자열 형태로 출력그냥
System.out.println(arr);을 사용하면 → 배열의 요소가 아니라 배열의 타입과 해시코드를 나타내는 문자열이 출력됨1
[I@15db9742
1 2 3 4 5 6 7 8 9
import java.util.Arrays; import java.util.Collections; Integer[] arr = {5, 2, 8, 1, 3}; Arrays.sort(arr, Collections.reverseOrder()); System.out.println(Arrays.toString(arr)); // [8, 5, 3, 2, 1]
Arrays.sort(arr, Collections.reverseOrder());
→ 내림차순 정렬Collections.reverseOrder()→ 내림차순 정렬에 사용되는 비교 기준
int[]가 아닌Integer[]배열을 사용해야한다.int[]는 기본 자료형 배열Integer[]는 참조 자료형 배열Integer는int를 객체로 다루기 위한 래퍼 클래스Integer[]는Integer객체의 참조를 저장하는 배열
→
Collections.reverseOrder()는 객체를 비교하는Comparator를 반환한다. 따라서Arrays.sort(배열, Comparator)는 객체 배열에만 사용할 수 있어서int[]에는 적용할 수 없다.
최빈값 구하기
https://school.programmers.co.kr/learn/courses/30/lessons/120812
내 풀이
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Solution {
public int solution(int[] array) {
int[] answer = new int[1000];
for(int i = 0; i<array.length; i++) {
answer[array[i]] += 1;
}
int[] max = new int[3]; // 0: max 값 1: max 인덱스 2: 그 전 max 값
max[0] = 0;
for(int i = 0; i<answer.length; i++) {
if(answer[i] > max[0]) {
max[0] = answer[i];
max[2] = answer[i];
max[1] = i;
} else if (answer[i] == max[0]) {
max[2] = -1;
}
}
if (max[2] != -1) {
return max[1];
} else {
return -1;
}
}
}
더 나은 풀이
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public int solution(int[] array) {
int[] count = new int[1000];
for (int num : array) {
count[num]++;
}
int max = 0;
int answer = 0;
for (int i = 0; i < count.length; i++) {
if (count[i] > max) {
max = count[i];
answer = i;
} else if (count[i] == max) {
answer = -1;
}
}
return answer;
}
}
향상된 for문 사용
for(int num : array)를 사용해 배열의 요소를 하나씩 꺼내서 num에 대입max 배열 대신 변수 사용
별도의 중복 확인을 위해 배열을 만들었었는데, 필요하지 않기 때문에 변수로 바로 최빈값 확인 가능
끝까지 for문을 돌면서 최빈값이 중복되면 -1, 저장해둔 max 값보다 새로운 값이 더 크면 다시 최빈값으로 저장
다른 풀이
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.util.HashMap;
class Solution {
public int solution(int[] array) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int num : array) {
map.put(num, map.getOrDefault(num, 0) + 1);
}
int max = 0;
int answer = 0;
for (int num : map.keySet()) {
int count = map.get(num);
if (count > max) {
max = count;
answer = num;
} else if (count == max) {
answer = -1;
}
}
return answer;
}
}
HashMap활용
문제에서는 배열을 사용하는 게 더 간단하지만, 숫자의 범위가 크거나 음수가 포함된다면HashMap을 사용하는 방법도 있음map.put(num, map.getOrDerfault(num, 0) + 1);→getOrDefault(num, 0)은 해당 숫자가 이미 저장되어 있으면 기존 등장 횟수를 가져오고, 없으면 0을 반환한다.
짝수는 싫어요
https://school.programmers.co.kr/learn/courses/30/lessons/120813
풀이
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.util.ArrayList;
import java.util.Arrays;
class Solution {
public int[] solution(int n) {
ArrayList<Integer> array = new ArrayList<>();
for(int i = 1; i<=n; i++) {
if(i%2 != 0) {
array.add(i);
}
}
int[] answer = array.stream().mapToInt(Integer::intValue).toArray();
return answer;
}
}
answer에 배열을 반환해야 하는데, 문제를 풀면서 배열에 몇 개의 값이 들어갈지 모르기 때문에 ArrayList를 사용했다.
ArrayListJava에서 제공하는 크기가 동적으로 변하는 배열 기반의 자료구조
- 처음에 요소의 개수를 지정하지 않아도 됨
- 요소 추가하면 필요에 따라 내부 저장 공간이 자동으로 확장됨
arr.size()로 요소 개수 확인int,double같은 기본 자료형을 타입 인자로 사용할 수 없음int대선 래퍼 클래스인Integer를 사용함
int[] answer = array.stream().mapToInt(Integer::intValue).toArray();stream()→ 리스트의 요소를 순서대로 처리할 수 있도록Strem생성mapToInt(Integer::intValue)→Integer객체들을 기본 자료형int값으로 변환toArray()→ 변환된 값들을 배열에 담아 반환
- ArrayList로 선언
ArrayList<Integer> array = new ArrayList<>();
→ 변수 타입:
ArrayList, 실제 생성 객체:ArrayList- List로 선언
List<Integer> array = new ArrayList<>();
→ 변수 타입:
List, 실제 생성 객체:ArrayList⇒
List는 인터페이스이고,ArrayList는 List 인터페이스를 구현한 클래스- List로 선언하는 이유
List<Integer> array = new ArrayList<>();로 선언했다가 나중에LinkedList로 변경하고 싶다면 →List<Integer> array = new LinkedList<>();로 객체를 생성하는 부분만 변경하면 됨 (물론 LinkedList도 별도로 import 해야함)
⇒ 따라서, 일반적으로 변수는 인터페이스 타입으로 선언하고, 실제 객체는 구현 클래스로 생성하는 방식을 사용함
뒤집힌 문자열
https://school.programmers.co.kr/learn/courses/30/lessons/120822
Java 문자열
문자열 선언 및 초기화
String str = "Hello";String str2 = new String("Hello");문자열 연결
Java에서는+연산자를 사용해 문자열을 연결할 수 있다.문자열 비교
문자열의 내용을 비교할 때는equals()를 사용해야한다.==를 사용하지 못하는 이유 → 두 변수가 같은 객체를 참조하는지 주소를 비교하기 때문문자열은 불변 객체
Java의String은 한 번 생성하면 객체의 내용을 변경할 수 없다.1 2 3 4 5
String str = "Hello"; str.replace("H", "J"); System.out.println(str); // Hello
→
replace()는 원본 문자열을 수정하는 것이 아니라 새로운 문자열을 반환한다.1 2 3
str = str.replace("H", "J"); System.out.println(str); // Jello
외계행성의 나이
https://school.programmers.co.kr/learn/courses/30/lessons/120834
풀이
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public String solution(int age) {
String answer = "";
String alpha = "abcdefghij";
String str = String.valueOf(age);
for (int i = 0; i < str.length(); i++) {
int num = str.charAt(i) - '0';
answer += alpha.charAt(num);
}
return answer;
}
}
숫자를 문자열로 변환
String str = String.valueOf(age);→ 숫자를 문자열로 변환해charAt()을 이요해 각 자릿수에 접근할 수 있게됨문자를 숫자로 변환
int num = str.charAt(i) - '0';→charAt()은char타입을 반환함 ⇒ 필요한 건 정수형 숫자 인덱스! → Java에서 문자끼리 빼기 연산을 하면 유니코드 값을 기준으로 계산해주기 때문에‘2’ - ‘0’과 같이 숫자 문자를 정수로 변환해줌



댓글
궁금한 점, 피드백, 오류 제보를 남겨 주세요.