Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 파이썬
- 금융데이터분석
- LV1
- 국내주식마감시황
- 금융데이터분석가
- 파이썬 함수
- 코스닥
- pml4
- 큐
- adx
- talib
- 인스턴스변수
- 자료구조
- 프로그래머스
- 파이썬정렬
- magic method
- 파이썬 알고리즘
- 클래스
- 파이썬 자료구조
- 퀀트매매
- bigo
- 차별화장세
- 스택
- Ta-Lib
- 코스피
- VariableScope
- 시스템 수준 입출력
- 서울디지털인재개발원
- 금융데이터서비스분석가
- unix i/o
Archives
- Today
- Total
IT Studying
자료구조 스택(Stack) 본문
반응형
이번 포스팅에서는 자료구조 중 스택에 대해서 알아보도록 하겠습니다.
1. 스택이란?
- 스택은 push연산으로 값을 입력받은 순서대로 삽입하고, pop연산으로 가장 최근에 삽입된 값을 삭제하는 자료구조입니다. 이 삽입/삭제 원칙을 후입선출(LIFO) 원칙이라고 합니다.
2. 스택의 코드 구현
class Stack:
def __init__(self): ##생성자 Stack클래스 생성
self.items = []
def push(self, val): ## push 기능 구현
self.items.append(val)
def pop(self): ## pop 기능 구현 .. 여기까지 필수
return self.items.pop()
def top(self): ## pop될 때 나오는 가장 마지막에 입력된 데이터
return self.items[-1]
def __len__(self): ## Stack에 입력되어 있는 데이터 수
return len(self.items)
def isEmpty(self): ## 스택이 비어있을 때
return self.__len__() == 0
- init생성자로 인스턴스를 생성할 수 있습니다. S = Stack() -> 자동으로 S라는 Stack의 인스턴스가 생성됩니다.
- append는 list 끝에 요소를 추가하는 메소드입니다. pop은 list 끝 요소를 제거하는 메소드입니다. pop은 제거되는 요소를 출력해줍니다.
- __init__, push, pop은 스택의 필수적인 요소고, 스택의 특성을 활용하여 알고리즘 짤 때 유용한 요소들을 Stack클래스에 구현해 놓을 수 있습니다. top 메소드는 가장 마지막에 입력된 데이터를 알 수 있습니다. len메소드로 Stack의 길이를 알 수 있고, isEmpty메소드로 스택이 비어있는지 확인 할 수 있습니다.
3. 스택의 응용 예제(Infix to Postfix)
이번에는 문제를 풀면서 스택이 어떻게 활용되는지 살펴보도록 하겠습니다. 우리가 흔히 사용하는 연산식, 예를 들면
'1 + (2 + 3) / 5'이러한 연산식은 연산할 요소 가운데(In)에 연산자가 존재하여 Infix방식이라고 부릅니다. Postfix방식은 연산할 요소 뒤에 연산자가 존재합니다. 이를테면 2+3 -> 23+로 표현하는 것입니다. 위 식을 Postfix방식으로 표현하면
'123+5/+'가 됩니다. 수식을 Infix방식으로 입력받았을 때 이것을 Postfix방식으로 바꾸는 문제를 풀어보도록하겠습니다.
class Stack:
def __init__(self):
self.items = []
def push(self, val):
self.items.append(val)
def pop(self):
return self.items.pop()
def top(self):
return self.items[-1]
def __len__(self):
return len(self.items)
def isEmpty(self):
return self.__len__() == 0 ## 스택 정의
prec = {'(': 3, '*': 1, '/': 1, '+': 2, '-': 2, '^': 0} ## 연산자 우선순위 정의. 값을 통해서 비교
def infix_to_postfix(infix):
opStack = Stack() ## 인스턴스 생성
outstack = [] ## 스택에서 값을 꺼내서 넣을 리스트 생성
token_list = infix.split() ## 입력 받은 값을 ' '(스페이스)로 구분
for token in token_list:
if token == '(':
opStack.push(token) ## ()가 최우선 연산순위이므로 나중에 괄호가 닫히게 되면 안에 있는 연산을 한번에 수행
elif token == ')':
while (opStack.top() != "("):
outstack.append(opStack.top()) ## ()내의 연산자들을 스택에 차례로 append
opStack.pop() ## append되었으니 스택에서 제거
opStack.pop() ## 스택에 있는 '('제거
elif token in '+-/*^': ## 연산자일 경우 우선순위에 따라 연산
if opStack.isEmpty():
opStack.push(token) ## 스택에 비어있으니 일단 push
elif prec.get(token) < prec.get(opStack.top()): ##스택이 비어 있지 않으면 우선순위를 비교
opStack.push(token)
else:
while prec.get(token) >= prec.get(opStack.top()): ## while문 실행으로 token에 비해 우선 순위높은 연산자들을 append
outstack.append(opStack.top())
opStack.pop()
if opStack.isEmpty():
break
opStack.push(token) ## 토큰을 스택에 추가하고 다시 for문 반복
else: ##토큰이 operand(숫자)일 경우 리스트에 값을 추가해줍니다.
outstack.append(token)
while opStack: ##for문이 끝나고 Stack에 남아 있는 연산자들을 리스트에 append합니다.
outstack.append(opStack.top())
opStack.pop()
return " ".join(map(str,outstack))
infix_expr = input()
postfix_expr = infix_to_postfix(infix_expr)
print(postfix_expr)
- 우선 스택 클래스를 정의합니다. 그 다음 prec딕셔너리를 통해 연산자마다의 우선순위를 정해줍니다. 추후 if문을 통해 우선순위에 따라 스택에서 push 또는 pop할 수 있습니다.
- ()가 최우선 연산순위이므로, 토큰이 '('일 때 스택에 저장해둡니다. 그리고 토큰이 ')'이 되면 괄호가 닫힌 것이므로, 괄호 내의 연산을 '('가 나올 때까지 수행해주면 됩니다.
- 토큰이 연산자일 때, 예를 들면 2+3*5면 235*+가 되고, 2-3+5면 23-5+가 됩니다. 2+3*5의 경우 토큰이 *일 때 스택에 +가 있을 것입니다. 이럴 때 스택에 *를 push하고 5를 리스트에 추가를 하면 스택에 +*순으로 남게됩니다. 해당 값을 차례로 pop해서 리스트에 append하면 원하는 후순위 식이됩니다. 하지만 2-3+5일 때 위의 방식으로 하면 이상해집니다. 그러므로 연산 우선순위가 같거나 낮을 경우 스택의 연산자를 pop해서 리스트에 append시켜 줘야됩니다. 만약 우선순위가 높은 연산자의 경우는 스택에 push하면 됩니다.
- 숫자들의 순서는 바뀌지 않으므로 토큰이 숫자이면 리스트에 그대로 append해줍니다.
궁금하신 사항이나 잘못된 내용이 있으면 댓글로 알려주시면 감사하겠습니다~
반응형
'파이썬 > 파이썬 자료구조' 카테고리의 다른 글
자료구조 디큐(dequeue) (0) | 2023.02.18 |
---|---|
자료구조 큐(Queue) (0) | 2023.02.18 |
파이썬 리스트 (0) | 2023.02.17 |
시간복잡도(BigO) (0) | 2023.02.17 |
파이썬 클래스(feat. 객체지향 프로그래밍) (1) | 2023.02.17 |
Comments