1. 스택(Stack)이란?
스택(Stack)은 후입선출(Last In, First Out, LIFO) 방식으로 데이터를 관리하는 자료구조이다.
- 가장 최근에 추가된 데이터가 가장 먼저 제거된다.
- 흔히 접시를 쌓는 방식에 비유된다. 위에 쌓은 접시를 먼저 꺼내는 것과 유사하다.
2. 스택에서 지원하는 주요 연산
1. push()
: 데이터를 스택에 추가
2. pop()
: 스택에서 가장 위의 데이터를 제거하고 반환
3. peek()
: 스택의 가장 위 데이터를 제거하지 않고 확인
4. isEmpty()
: 스택이 비어 있는지 확인
5. size()
: 스택에 있는 데이터의 개수를 반환
3. Java에서 스택 구현
Java에선는 java.util.Stack
클래스를 사용하여 스택을 구현할 수 있다. 이 클래스는 Vector
를 상속받아 스택의 주요 기능을 제공한다.
4. 사용 예시
예제 1 : 기본적인 스택 연산
import java.util.Stack;
public class StackExample {
public static void main(String[] args) {
// 스택 생성
Stack<Integer> stack = new Stack<>();
// 데이터 추가 (push)
stack.push(10);
stack.push(20);
stack.push(30);
System.out.println("스택: " + stack); // [10, 20, 30]
// 데이터 제거 (pop)
System.out.println("pop: " + stack.pop()); // 30
System.out.println("스택: " + stack); // [10, 20]
// 가장 위의 데이터 확인 (peek)
System.out.println("peek: " + stack.peek()); // 20
// 스택이 비어 있는지 확인
System.out.println("isEmpty: " + stack.isEmpty()); // false
// 스택 크기 확인
System.out.println("size: " + stack.size()); // 2
}
}
출력 결과 :
스택: [10, 20, 30]
pop: 30
스택: [10, 20]
peek: 20
isEmpty: false
size: 2
예제 2 : 문자열 뒤집기
스택은 문자열을 뒤집는 데 유용하게 사용할 수 있다.
import java.util.Stack;
public class ReverseString {
public static void main(String[] args) {
String input = "hello";
Stack<Character> stack = new Stack<>();
// 문자열의 각 문자를 스택에 push
for (char ch : input.toCharArray()) {
stack.push(ch);
}
// 스택에서 pop하여 문자열을 뒤집음
StringBuilder reversed = new StringBuilder();
while (!stack.isEmpty()) {
reversed.append(stack.pop());
}
System.out.println("원본 문자열: " + input);
System.out.println("뒤집힌 문자열: " + reversed);
}
}
출력 결과 :
원본 문자열: hello
뒤집힌 문자열: olleh
예제 3 : 괄호 검사
스택은 수식의 괄호가 올바르게 닫혔는지 확인하는 데 유용하다.
import java.util.Stack;
public class ParenthesisCheck {
public static void main(String[] args) {
String expression = "({[()]})";
System.out.println("올바른 괄호인가? " + isValid(expression));
}
public static boolean isValid(String expression) {
Stack<Character> stack = new Stack<>();
for (char ch : expression.toCharArray()) {
// 여는 괄호는 스택에 push
if (ch == '(' || ch == '{' || ch == '[') {
stack.push(ch);
}
// 닫는 괄호는 스택에서 pop하여 짝이 맞는지 확인
else if (ch == ')' && !stack.isEmpty() && stack.peek() == '(') {
stack.pop();
} else if (ch == '}' && !stack.isEmpty() && stack.peek() == '{') {
stack.pop();
} else if (ch == ']' && !stack.isEmpty() && stack.peek() == '[') {
stack.pop();
}
// 짝이 맞지 않으면 false
else {
return false;
}
}
// 스택이 비어 있으면 모든 괄호가 올바르게 짝지어진 것
return stack.isEmpty();
}
}
출력결과 :
올바른 괄호인가? true
5. 스택의 활용 예시
1) 괄호 검사 : 수학식, 코드 블록의 여는 괄호와 닫는 괄호의 짝을 확인할 때 사용
2) 문자열 뒤집기 : 문자열을 뒤집는 간단한 알고리즘에 활용
3) 수식 계산 : 중위표기법, 후위표기봅 계산에 활용
4) DFS(깊이 우선 탐색) : 그래프 탐색에서 스택을 활용
5) Undo/Redo 구현 : 텍스트 에디터 등에서 실행 취소/재실행 기능에 활용
6. 주의점
- Stack
은 동기화 되어 있기 때문에 멀티스레드 환경에서는 안전하지만, 성능이 다소 느릴 수 있다.
- 대안 : 멀티스레드 환경이 아니거나 성능이 중요한 경우 Deque
(ArrayDeque)를 사용해 스택처럼 사용할 수 있다.
예 :
Deque<Integer> stack = new ArrayDeque<>();
stack.push(10);
stack.pop();
'java' 카테고리의 다른 글
[Java] int형 숫자의 자릿수 구하기 (0) | 2024.11.28 |
---|