[계획]
1. 백준 실버5 이상 문제 1문제 풀기.
2. 5차시 활동 때 막혔던 문제 공부하기.
- 별찍기 과정에서 BufferedReader를 사용해 입력받았을 때 원하는대로 안찍히는지 (코드문제?)
- '공사장 표지판' 문제에서 내가 처음 짠 코드가 어느부분이 잘못되었는지 (출력형식과 맞지 않음.)
[회고]
오늘은 백준 1문제와 5차시 활동을 하면서 궁금했던 점들을 공부했다.
1. 실버5 : 좌표 정렬하기 (11650번)
문제 : https://www.acmicpc.net/problem/11650
11650번: 좌표 정렬하기
첫째 줄에 점의 개수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N개의 줄에는 i번점의 위치 xi와 yi가 주어진다. (-100,000 ≤ xi, yi ≤ 100,000) 좌표는 항상 정수이고, 위치가 같은 두 점은 없다.
www.acmicpc.net
이 문제는 람다식을 사용해 sort하는 방법으로 풀었다.
람다식을 사용할 줄 안다면 이 문제는 쉽게 풀리는 문제였다. (물론 나는 몰라서 찾아봤다...ㅎㅎ)
아래는 내가 작성한 코드다.
package silver5;
import java.util.*;
public class point_sort_11650_0127 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int N = sc.nextInt(); // 입력받는 줄수
sc.nextLine();
int[][] data = new int[N][2];
int[] temp = new int[2];
for(int i = 0; i < N; i++){
String[] str = sc.nextLine().split(" ");
data[i][0] = Integer.parseInt(str[0]);
data[i][1] = Integer.parseInt(str[1]);
}
Arrays.sort(data, (t1, t2) -> { // y좌표 정렬
if(t1[0] == t2[0]){
return t1[1] - t2[1];
}
else {
return t1[0] - t2[0];
}
});
for(int i = 0; i < N; i++){
System.out.println(data[i][0] + " " + data[i][1]);
}
sc.close();
}
}
입력을 받아 2차원배열에 넣어주었다.
그 후 값이 저장되어 있는 2차원배열을 조건에 맞춰 정렬하면 되는 문제였는데 2차원 정렬을 한번도 해본 적 없어 찾아보았다.
Arrays.sort에 있는 Comparator를 조건에 맞게 작성해주면 되었다.
그래서 문제에 제시된 대로 x좌표를 오름차순으로 정렬한 뒤 x좌표가 같다면 y좌표를 오름차순으로 정렬하도록 코드를 작성해주었다. 아래는 람다식이 아닌 Comparator를 사용한 코드이다.
Arrays.sort(data, new Comparator<int[]>() {
@Override
public int compare(int[] t1, int[] t2) {
if(t1[0] == t2[0]){
return t1[1] - t2[1];
}
else {
return t1[0] - t2[0];
}
}
});
이렇게 코드를 작성했을 때 new Comparator부분에 노란색 전구가 떠서 확인해 본 결과 'Replace with Rambda' 즉, 람다식으로 바꿔보라고 조언을 해주었다. 그래서 클릭해봤더니
Arrays.sort(data, (t1, t2) -> {
if(t1[0] == t2[0]){
return t1[1] - t2[1];
}
else {
return t1[0] - t2[0];
}
});
이런식으로 람다식으로 바뀌면서 매우 간단해졌다.
이 람다식으로 정렬을 해준 뒤 출력을 해주면 문제가 해결된다.
람다식을 잘 몰랐지만 오늘 '좌표 정렬하기' 문제를 풀면서 이해가 되었다.
- BufferedReader로 별찍기
public class test_everything {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
Scanner sc = new Scanner(System.in);
int N = Integer.parseInt(br.readLine());
System.out.println(N);
for(int i = 1; i <= N; i++){
for(int j = 0; j < N-i; j++){
System.out.print(" ");
}
for(int k = 0; k < i; k++){
System.out.print("*");
}
System.out.println();
}
}
}
BufferedReader로 입력을 받아 Integer.parseInt()을 사용해 String타입을 Int형으로 바꿔 별찍기를 했을 때 아래와 같이 정상적으로 출력이 되는 것을 볼 수 있다.
br.readLine() 입력
public class test_everything {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
Scanner sc = new Scanner(System.in);
int N = br.read();
System.out.println(N);
for(int i = 1; i <= N; i++){
for(int j = 0; j < N-i; j++){
System.out.print(" ");
}
for(int k = 0; k < i; k++){
System.out.print("*");
}
System.out.println();
}
}
}
하지만 위의 코드처럼 BufferedReader로 입력받아 br.read()로 입력받아 별을 찍어보면 아래와 같은 결과가 나오게 된다.
br.read() 입력
그래서 차이점을 알아보게 되었다.
- readLine() : Scanner에서 nextLine()처럼 한줄을 통째로 입력받는 방식. String값으로 읽어옴. |
- read() : 값을 읽어올 때 int값으로 변형해서 읽어오는 방식. => 만약 1을 read()를 통해 읽어온다면 ASCII형식의 문자값 '1'을 읽어오게 되고, 결국 최종적으로 '1'의 int형값인 49를 읽어오게 된다. |
ASCII코드는 다음을 참조 : https://ko.wikipedia.org/wiki/ASCII
ASCII - 위키백과, 우리 모두의 백과사전
1972 프린터 사용 설명서에 개시된 아스키 코드 차트표 미국정보교환표준부호(영어: American Standard Code for Information Interchange), 또는 줄여서 ASCII( , 아스키)는 영문 알파벳을 사용하는 대표적인 문자
ko.wikipedia.org
BufferedReader에서 사용되는 readLine()과 read()의 차이가 있었다. 나는 이것을 모르고 계속 사용해 원하는 값이 나오지 않았다.
BufferedReader로 수를 입력받을 때 readLine()을 사용한다면 Integer.parseInt(br.readLind()) 방법을 사용하면 되고, read()를 사용하고 싶다면 br.read() - '0' 을 사용하면 된다.
※ 결론!
BufferedReader 이기 때문에 원하는 갯수만큼 안찍힌 것이 아니라 read()를 사용할 때 ASCII의 값을 가져온다는 것을 모르고 사용했기 때문에 원하는 모양이 나오지 않았던 것이다.
- '공사장 표지판' 문제에서 내가 처음 짠 코드가 어느부분이 잘못되어서 출력형식과 맞지 않는지 아직도 잘 모르겠다...
'2022-winter-mogakko' 카테고리의 다른 글
2022-모각코 5차시 활동 계획 및 결과 (0) | 2022.02.04 |
---|---|
2022-모각코 4차시 활동 계획 및 결과 (0) | 2022.02.04 |
2022-모각코 3차시 활동 계획 및 결과 (0) | 2022.02.04 |
2022-모각코 2차시 활동 계획 및 결과 (0) | 2022.02.04 |