4주차_백준 문제풀이
목차
1. 문제 1935
2. 문제 10808
3. 문제 2751
1. 문제 1935
풀이
package etc;
import java.io.*;
import java.util.Scanner;
import java.util.Stack;
public class baekjoon1935 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int num = Integer.parseInt(br.readLine());
String data = br.readLine();
double[] arr = new double[num];
for(int i = 0; i < num; i++) {
arr[i] = Double.parseDouble(br.readLine());
}
Stack<Double> stack = new Stack<>();
double result = 0;
for(int i = 0; i < num; i++) {
if('A' <= data.charAt(i) && data.charAt(i) <= 'Z') {
stack.push(arr[data.charAt(i)- 'A']);
} else {
if(!stack.isEmpty()) {
double first = stack.pop();
double second = stack.pop();
switch (data.charAt(i)) {
case '+':
result = second + first;
stack.push(result);
continue;
case '-':
result = second - first;
stack.push(result);
continue;
case '*':
result = second * first;
stack.push(result);
continue;
case '/':
result = second / first;
stack.push(result);
continue;
}
}
}
}
System.out.printf("%.2f", stack.pop());
br.close();
}
}
기본설명
중위 표기식(Infix Expression)
- 일반적으로 사용하는 표기식으로 연산자가 피연산자 사이에 들어간다.
- 연산자를 만나면 뒤에 있는 두 피연산자를 계산하고, 다시 연산자가 나오면 피연산자를 계산하는 방법
후위 표기식(postfix expression)
- 연산자가 피연산자 뒤에 나온다.
stack를 이용해 연산자가 나오면 push 하고,
피연산자 *를 만나면 위에 -3와 4를 pop하여 결과값 -12를 다시 push하도록 하여 마지막엔 결과값만 stack에 남게 한다.
코드설명
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int num = Integer.parseInt(br.readLine()); // 입력받을 개수
String data = br.readLine(); // 입력 받은 후위연산자
double[] arr = new double[num]; // num만큼 배열 생성후
for(int i = 0; i < num; i++) {
arr[i] = Double.parseDouble(br.readLine()); // num만큼 double타입으로 배열에 넣기
}
Stack<Double> stack = new Stack<>(); // 피연산자 넣을 stack 생성
num 크기 만큼 arr 배열 생성 후 charAt으로 피연산자와 연산자를 구분할 것이다.
stack에 연산자를 넣고 피연산자를 만나면 두개의 값이 pop하여 계산 후 다시 push하는 반복문을 생성할 것이다.
for(int i = 0; i < num; i++) {
if('A' <= data.charAt(i) && data.charAt(i) <= 'Z') {
stack.push(arr[data.charAt(i)- 'A']);
} else {
if(!stack.isEmpty()) {
double first = stack.pop();
double second = stack.pop();
switch (data.charAt(i)) {
case '+':
result = second + first;
stack.push(result);
continue;
case '-':
result = second - first;
stack.push(result);
continue;
case '*':
result = second * first;
stack.push(result);
continue;
case '/':
result = second / first;
stack.push(result);
continue;
}
}
}
}
A는 arr[0], B는 arr[1], C는 arr[2] .. 에 있는 숫자에 해당되기 때문에 data.charAt(i) - 'A'의 arr 값을 push해준다.
이후 + - * /를 만나면 pop을 2번 한 후 계산한 result 값을 stack에 push한다.
최종적으로 남아있는 stack 값이 마지막 결과 값이다.
2. 문제 10808
풀이
package etc;
import java.io.*;
public class baekjoon10808 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int[] arr = new int[26];
String str = br.readLine();
for (int i=0;i<str.length();i++) {
char c = str.charAt(i);
arr[c - 97]++;
}
for (int i = 0; i<26; i++) {
System.out.print(arr[i] + " ");
}
}
}
코드설명
기본적으로 알아두면 좋을 아스키코드 값
- 숫자 0 = 48
- 대문자 A = 65
- 소문자 a = 97
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int[] arr = new int[26]; //크기가 26개인 배열 생성
String str = br.readLine();
알파벳의 개수는 26개 이므로 크기가 26개인 배열을 생성해준다.
for (int i=0;i<str.length();i++) {
char c = str.charAt(i); //str의 문자열을 char로 하나씩 받는다.
arr[c - 97]++; //소문자 a의 아스키코드 값을 빼서 arr 값을 증가시켜준다.
}
for (int i = 0; i<26; i++) {
System.out.print(arr[i] + " "); // 띄어쓰기한 후 출력한다.
}
크기가 26인 int형 배열 arr을 선언해주고 각 char에서 arr[char - 97]++해주면 알파벳의 개수를 셀 수 있다.
3. 문제 2751번
풀이
package etc;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
public class baekjoon2751 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int num = Integer.parseInt(br.readLine());
ArrayList<Integer> arr = new ArrayList<>();
for(int i=0; i<num;i++) {
arr.add(Integer.parseInt(br.readLine()));
}
Collections.sort(arr);
for(int value : arr) {
sb.append(value).append('\n');
}
System.out.println(sb);
}
}
코드설명
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //Scanner대신 BufferReader사용
StringBuilder sb = new StringBuilder(); //추후에 append를 사용할 것이기 때문에 StringBuilder사용
int num = Integer.parseInt(br.readLine()); //BufferReader의 기본값인 String을 Integer로 바꾼다.
ArrayList<Integer> arr = new ArrayList<>(); //Collection.sort를 사용하기 위해 List<T> 생성
for(int i=0; i<num;i++) {
arr.add(Integer.parseInt(br.readLine())); //List에 br.readLine 값 추가
}
Collections.sort(arr); //내림차순 정렬
for(int value : arr) {
sb.append(value).append('\n'); //sb에 value값과 /n값을 append
}
System.out.println(sb);
오류
처음에 sort가 Comparable<T> 인터페이스를 이용하는 줄 모르고 아래와 같은 일반 배열을 생성했었다.
int[] arr = new int[num];
for(int i = 0; i < num; i++) {
arr[i] = Integer.parseInt(br.readLine());
}
The method sort(List<T>) in the type Collections is not applicable for the arguments (int[])
그러자 sort() 메소드의 매개변수 타입을 보면 List<T>로 제네릭 타입을 받고 있다.
ArrayList<Integer> arr = new ArrayList<>();
그래서 ArrayList Integer타입을 생성해주어 오류가 해결되었다.