스택은 자료 구조의 한 종류로, 후입선출(LIFO, Last In First Out) 방식으로 동작합니다. 즉, 나중에 들어간 데이터가 먼저 나오는 구조입니다. 흔히 접시를 쌓아놓는 것을 생각하면 이해하기 쉽습니다. 새 접시는 가장 위에 놓고, 사용할 때도 가장 위에 있는 접시부터 사용하는 방식입니다.
스택은 여러 가지 이유로 유용합니다. 특히, 데이터의 순서를 유지하거나 되돌릴 필요가 있는 경우에 유용합니다. 예를 들어, 웹 브라우저의 뒤로 가기 기능이나 텍스트 에디터의 되돌리기 기능은 스택을 사용하여 구현됩니다. 이러한 기능은 사용자가 마지막으로 한 작업을 기억하고 이를 되돌릴 수 있어야 하므로, 후입선출 방식이 잘 맞습니다.
파이썬에서 스택을 사용하려면 기본 리스트(list)를 이용할 수 있습니다. 리스트의 append() 메서드로 데이터를 추가하고, pop() 메서드로 데이터를 제거할 수 있습니다.
# 스택 생성
stack = []
# 스택에 데이터 추가
stack.append(1)
stack.append(2)
stack.append(3)
# 스택에서 데이터 제거
print(stack.pop()) # 출력: 3
print(stack.pop()) # 출력: 2
print(stack.pop()) # 출력: 1
위 코드에서 보듯이, 데이터를 추가할 때는 append()를 사용하고, 제거할 때는 pop()을 사용합니다. 이렇게 하면 스택의 후입선출 특성을 유지할 수 있습니다.
스택의 사용 예시는 다양합니다. 그 중에서도 괄호의 짝을 맞추는 문제를 해결하는 데 스택을 사용할 수 있습니다. 예를 들어, 문자열에 있는 괄호가 올바르게 짝지어져 있는지 확인하는 코드를 작성할 수 있습니다.
def is_valid_parentheses(s):
stack = []
mapping = {')': '(', '}': '{', ']': '['}
for char in s:
if char in mapping:
top_element = stack.pop() if stack else '#'
if mapping[char] != top_element:
return False
else:
stack.append(char)
return not stack
# 테스트
print(is_valid_parentheses("(){}[]")) # 출력: True
print(is_valid_parentheses("([)]")) # 출력: False
print(is_valid_parentheses("{[]}")) # 출력: True
위 코드에서, 스택을 사용하여 괄호의 짝을 맞추는 과정을 구현했습니다. 열린 괄호는 스택에 추가하고, 닫힌 괄호가 나왔을 때는 스택에서 꺼내어 짝이 맞는지 확인합니다.
스택을 사용할 때는 몇 가지 주의할 점이 있습니다. 먼저, 스택의 크기를 관리하는 것이 중요합니다. 무한히 데이터를 추가하면 메모리가 부족해질 수 있으므로, 적절한 크기로 제한하는 것이 좋습니다. 또한, 스택이 비어있을 때 pop()을 호출하면 에러가 발생하므로, 이를 방지하기 위해 항상 스택이 비어있는지 확인하는 습관을 가지는 것이 좋습니다.
# 안전한 pop 사용 예시
if stack:
print(stack.pop())
else:
print("스택이 비어있습니다.")
이렇게 하면 스택이 비어 있을 때 발생할 수 있는 에러를 방지할 수 있습니다.