💿 Stack
🔍 스택의 활용 예시
Memoization
DP(Dynamic Programming)
# 스택구현해서 값 넣어보기
# class로 구현해보기
class Stack:
'''
속성 : 실제 데이터를 저장할 배열(리스트) - 고정길이,top
마지막 원소를 가리키는 변수 ( Stack pointer )
기능 : push, pop, peek, size, is_Empty
'''
def __init__(self, length):
self.stack = [None]*length
self.top = -1
'''
top의 초기화 값 : -1 default
'''
# 요소를 stack 마지막에 저장하고, 만약에 가득차서 못넣을 경우, 'overflow' 출력
def push(self, val):
if self.is_full():
print('overflow')
else:
self.top += 1
self.stack[self.top] = val
# 마지막 요소를 삭제하고, 반환, 요소가 없는 경우 'underflow' 출력
def pop(self):
if self.is_empty():
print('underflow가났습니다.')
return None
else:
self.top -= 1
return self.stack[self.top + 1]
# 마지막 요소를 반환, 요소가 없으면 'underflow'
def peek(self):
if self.is_empty():
print('underflow가났습니다.')
return None
else:
return self.stack[self.top]
# 현재 요소의 개수 반환
def size(self):
return self.top+1
def is_empty(self):
if self.top == -1:
return True
return False
# 요소가 가득 찼으면 True, 아니면 False
def is_full(self):
if self.top == len(self.stack)-1:
return True
return False
my_stack = Stack(10)
my_stack.push(1)
my_stack.push(2)
my_stack.push(3)
my_stack.push(4)
my_stack.push(5)
my_stack.push(6)
my_stack.push(7)
my_stack.push(8)
my_stack.push(9)
my_stack.push(10)
print(my_stack.pop())
print(my_stack.pop())
print(my_stack.pop())
print(my_stack.pop())
print(my_stack.pop())
print(my_stack.pop())
print(my_stack.pop())
print(my_stack.pop())
print(my_stack.peek(), my_stack.size(), my_stack.is_full(), my_stack.is_empty())
def fibo(n):
if n < 2:
return n
else:
return fibo(n-1) + fibo(n-2)
재귀함수로 앞에서 피보나치를 구하는 함수를 작성했는데, 여기에는 큰 문제가 있다.
바로, fibo함수의 호출 수가 커질수록 ”엄청난 중복 호출이 존재” 하게 된다는 것이다.
이 문제를 해결하기 위해서 아주 간단한 아이디어를 사용하면 된다.
바로, 프로그램이 실행할 때 이전에 계산한 값을 메모리에 저장해서 매번 다시 계산하지 않도록 하여 전체 실행 속도를 빠르게 하는 기술이다. == Memoization
이는, 동적 계획법의 핵심이 되는 기술이다.
# memo를 위한 배열을 할당하고, 모두 0으로 초기화 한다.
# memo[0]을 0으로 memo[1]는 1로 초기화 한다.
def fibo1(n):
global memo
if n >= 2 and len(memo) <= n:
memo.append(fibo1(n-1) + fibo1(n-2))
return memo[n]
memo = [0, 1]
앞에서 Memoization을 공부하며 동적 계획법의 핵심이 되는기술 이라는 표현을 사용햇는데, 그렇다면 동적계획(Dynamic Programming)이란 뭘까?
부분 문제로 나누는 일을 끝냈으면 가장 작은 부분 문제부터 해를 구한다.
그 결과는 테이블에 저장하고, 테이블에 저장된 부분 문제의 해를 이용하여 상위 문제의 해를 구한다.
테이블 인덱스 | 저장되어 있는 값 |
---|---|
[0] | 0 |
[1] | 1 |
[2] | 1 |
[3] | 2 |
[4] | 3 |
[5] | 5 |
[6] | 8 |
… | … |
[n] | fibo(n) |
def fibo2(n):
f = [0, 1]
for i in range(2, n + 1):
f.append(f[i+1] + f[i-2])
return f[n]