자바의 자료구조 - 스택의 활용
드디어 본격적인 시작이다.
다시 한번 밝히지만 해당 포스팅들은 https://blog.encrypted.gg/919 이 출처이며,
해당 블로그의 포스팅을 공부하는 포스팅이다.
정확한 정보와 자세한 내용은 해당 블로그를 보는 것을 강력히 권한다.
: 수식의 괄호 쌍
간단한 스택의 활용이다. (, {, [ 등이 올때 Stack에 담고, 쌍이 맞는 ),},]이 올때 pop()을 시키어 해결하는 구조다.
: https://www.acmicpc.net/problem/10799
10799번: 쇠막대기
여러 개의 쇠막대기를 레이저로 절단하려고 한다. 효율적인 작업을 위해서 쇠막대기를 아래에서 위로 겹쳐 놓고, 레이저를 위에서 수직으로 발사하여 쇠막대기들을 자른다. 쇠막대기와 레이저
www.acmicpc.net
심화로 BOJ에서 이 문제를 풀어보도록 했다.
처음 접했을때 감이 오지 않았다.
import java.util.Scanner;
import java.util.Stack;
public class BOJ4949 {
//public class Main {
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
String q = sc.nextLine();
String answer = solution(q);
System.out.println(answer);
}
private static String solution(String q) {
Stack<Character> stack = new Stack<>();
boolean result = true;
for (int i = 0; i < q.length(); i++) {
if(q.charAt(i)=='(' || q.charAt(i)=='[') {
stack.push(q.charAt(i));
result = false;
}
if(q.charAt(i)=='.') break;
if(q.charAt(i)==')') {
if(!stack.isEmpty()) {
if(stack.peek().equals('(')) {
stack.pop();
result = true;
}
}
else {
result = false;
break;
}
}
if(q.charAt(i)==']') {
if(!stack.isEmpty()) {
if(stack.peek().equals('[')) {
stack.pop();
result = true;
}
}
else {
result = false;
break;
}
}
}
if(result) return "yes";
else return "no";
}
}
이런 방식으로 풀어봤는데 백준에서 자바를 사용하는 방법이 기존에 이용하던 프로그래머스와 달라서 애를 먹었다.
그러다 여러 줄을 다루는 방법에도 문제가 있었음을 깨달았다.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Stack;
public class BOJ4949 {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String q = "";
while((q = br.readLine()) != null) {
String answer = solution(q);
System.out.println(answer);
}
}
private static String solution(String q) {
Stack<Character> stack = new Stack<>();
boolean result = true;
for (int i = 0; i < q.length(); i++) {
if(q.charAt(i)=='(' || q.charAt(i)=='[') {
stack.push(q.charAt(i));
result = false;
}
if(q.charAt(i)=='.') break;
if(q.charAt(i)==')') {
if(!stack.isEmpty()) {
if(stack.peek().equals('(')) {
stack.pop();
result = true;
}
}
else {
result = false;
break;
}
}
if(q.charAt(i)==']') {
if(!stack.isEmpty()) {
if(stack.peek().equals('[')) {
stack.pop();
result = true;
}
}
else {
result = false;
break;
}
}
System.out.println("q.charAt(i) : "+q.charAt(i));
System.out.println("stack : "+stack);
System.out.println();
}
if(result) return "yes";
else return "no";
}
}
그래서 이렇게 해보았는데, 여러 줄은 다 처리가 됐는데
([ (([( [ ] ) ( ) (( ))] )) ]).
이게 나는 yes가 나오고, 답지는 no가 나와야 한다고 한다. 괄호 쌍은 맞지만, 문제구문중에
- 짝을 이루는 두 괄호가 있을 때, 그 사이에 있는 문자열도 균형이 잡혀야 한다.
이 내용에 위배되는게 아닌가 싶은데 도저히 문자열의 균형이라는게 어떤건지 모르겠다.
===============================================================
: https://www.acmicpc.net/problem/2504
불러오는 중입니다...
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Stack;
public class BOJ2504 {
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String q = br.readLine();
int a = solution(q);
bw.write(a+"");
bw.flush();
bw.close();
System.out.println();
}
private static int solution(String q) {
Stack<Character> s = new Stack<>();
Stack<Integer> p = new Stack<>();
Stack<Integer> stage = new Stack<Integer>();
int point = 0;
int count = 0;
for (int i = 0; i < q.length(); i++) {
char m = q.charAt(i);
int tool = 0;
if(m=='{') return 0;
if(m=='}') return 0;
if(m=='(') {
if(s.isEmpty()) {
s.push(m);
}else if(s.peek().equals('(')) {
s.push(m);
}else if(s.peek().equals('[')) {
s.push(m);
}else if(s.peek().equals(')')) {
s.push(m);
}else if(s.peek().equals(']')) {
s.push(m);
}
count++;
} else if(m=='[') {
if(s.isEmpty()) {
s.push(m);
}else if(s.peek().equals('(')) {
s.push(m);
}else if(s.peek().equals('[')) {
s.push(m);
}else if(s.peek().equals(')')) {
s.push(m);
}else if(s.peek().equals(']')) {
s.push(m);
}
count++;
} else if(m==')') {
if(s.isEmpty()) return 0;
if(s.peek().equals('(')) {
p.push(2);
s.push(m);
}else if(s.peek().equals(')')) {
if(p.size()>=2) {
if(count/2==0) {
while(true) {
if(!p.isEmpty()) tool += p.pop();
else break;
}
}else {
for (int j = 0; j < count/2; j++) {
tool = p.pop();
}
}
}else {
tool = p.pop();
}
p.push(tool*2);
s.push(m);
}else if(s.peek().equals(']')) {
if(p.size()>=2) {
if(count/2==0) {
while(true) {
if(!p.isEmpty()) tool += p.pop();
else break;
}
}else {
for (int j = 0; j < count/2; j++) {
tool = p.pop();
}
}
}else {
tool = p.pop();
}
p.push(tool*2);
s.push(m);
}else if(s.peek().equals('[')) {
return 0;
}
count--;
} else if(m==']') {
if(s.isEmpty()) return 0;
if(s.peek().equals('[')) {
p.push(3);
s.push(m);
}else if(s.peek().equals(')')) {
if(p.size()>=2) {
if(count/2==0) {
while(true) {
if(!p.isEmpty()) tool += p.pop();
else break;
}
}else {
for (int j = 0; j < count/2; j++) {
tool = p.pop();
}
}
}else {
tool = p.pop();
}
p.push(tool*3);
s.push(m);
}else if(s.peek().equals(']')) {
if(p.size()>=2) {
if(count/2==0) {
while(true) {
if(!p.isEmpty()) tool += p.pop();
else break;
}
}else {
for (int j = 0; j < count/2; j++) {
tool = p.pop();
}
}
}else {
tool = p.pop();
}
p.push(tool*3);
s.push(m);
}else if(s.peek().equals('(')) {
return 0;
}
count--;
}
if(count==0 && i != 0) {
stage.push(p.pop());
point = 0;
}
// System.out.println("s : "+s);
// System.out.println("p : "+p);
// System.out.println("count : "+count);
// System.out.println("stage : "+stage);
// System.out.println("point : "+point);
// System.out.println("====");
}
// while(true) {
// if(!p.isEmpty()) point += p.pop();
// else break;
// }
while(true) {
if(!stage.isEmpty()) point += stage.pop();
else break;
}
return point;
}
}
이래도 되나 싶을정도의 진행속도다.. 이렇게 복잡한것 8시간이나 걸렸다.
밖에서 하다보니 집중을 잘 못하기도 했지만 ㅠㅠ
그마저도 현 시점 오류가 있다. 좀 더 수정해봐야겠다.
이건..좀 더 기본기를 공부하고 다뤄봐야겠다.