01-1 스택이란?
01-2 배열 구조로 스택 구현하기
01-3 스택의 응용: 괄호 검사
01-4 파이썬에서 스택 사용하기
01-5 시스템 스택과 순환 호출
[그림]
자료형 확인 함수 type()
- 현재 변수에 저장된 값의 자료형을 출력하는 함수
[그림]
리스트(list)와 튜플(tuple)을 이용할 수 있음
배열의 원소들을 변결할 수 있어야 하므로 리스트 사용
- array[]: 스택 요소들을 저장할 배열
- capacity: 스택의 최대 용량. 저장할 수 있는 요소의 최대 개수(상수)
- top: 상단 요소의 위치(변수, 인덱스)
텍스트배열
- 요소들을 저장할 공간
용량(capacity)
- 한번 만들어지고 나면 고정되는 상수
top
- 인덱스를 저장하는 변수, 가장 최근에 삽입된 요소의 위치
capacity = 10 # 스택 용량: 예) 용량을 10으로 지정
array = [None]*capacity # 요소 배열 : [None, ..., None] (길이가 capacity)
top = -1 # 상단의 인덱스: 공백 상태(-1)로 초기화함
* 연산자를 이용해 같은 값을 나열하는 리스트 만들 수 있음
공백 상태와 포화 상태를 검사하는 isEmpty()와 isFull() 연산
[그림]
def isEmpty():
if top == -1: return True # 공백이면 True 반환
else: return False # 아니면 False 반환
def isFull(): return top == capacity-1 # 비교 연산 결과를 바로 반환
새로운 요소 e를 삽입하는 push(e) 연산
def push(e):
# global top
if not isFull(): # 포화 상태가 아닌 경우
top += 1 # top 증가
array[top] = e # top 위치에 e 복사
else: # 포화 상태: overflow
print("stack overflow")
exit()
상단 요소를 삭제하는 pop() 연산
def pop():
# global top
if not isEmpty(): # 공백 상태가 아닌 경우
top -= 1 # top 감소 (global top 선언 필요)
return array[top+1] # 이전(top+1) 위치의 요소 반환
else: # 공백 상태: underflow
print("stack underflow")
exit()
상단 요소를 들여다보는 peek() 연산
def peek():
if not isEmpty(): # 공백 상태가 아닌 경우
return array[top]
else: pass # underflow 예외는 처리하지 않았음
현재 스택 요소의 수를 반환하는 size() 연산
def size(): return top+1 # 현재 요소의 수는 top+1
전역 변수와 함수 구현 방법의 문제
- top을 전역 변수로 인식하지 못해 생기는 문제
- top을 전역 변수로 선언하는 global top 문장을 각 함수에 추가하여 간단히 해결할 수 있음
- 여러 개의 스택이 동시에 필요한 문제에 사용할 수 없음
클래스의 선언과 멤버변수 초기화
class ArrayStack:
def __init__(self, capacity):
self.capacity = capacity # 스택 용량
self.array = [None]*self.capacity # 요소 배열
self.top = -1 # 상단의 인덱스
def isEmpty(self): return self.top == -1
def isFull(self): return self.top == self.capacity-1
def push(self, item):
if not self.isFull():
self.top += 1
self.array[top] = item
else: pass
def pop(self):
if not self.isEmpty():
self.top -= 1
return self.array[top+1]
else: pass
def peek(self):
if not self.isEmpty():
return self.array[self.top]
else: pass
def size(): return self.top+1
s = ArrayStack(100)
msg = input('문자열 입력: ')
for c in msg:
s.push(c)
print("문자열 출력: ", end='')
while not s.isEmpty():
print(s.pop(), end='')
print()
소스코드나 주어진 문자열에서 괄호들이 올바르게 사용되었는지를 검사하는 문제
- 조건 1: 왼쪽 괄호의 개수와 오른쪽 괄호의 개수가 같아야 합니다.
- 조건 2: 같은 종류인 경우 왼쪽 괄호가 오른쪽보다 먼저 나와야 합니다.
- 조건 3: 다른 종류의 괄호 쌍이 서로 교차하면 안됩니다.
- 빈 스택을 준비함
- 입력된 문자를 하나씩 읽어 왼쪽 괄호를 만나면 스택에 삽입
- 오른쪽 괄호를 만나면 가장 최근에 삽입된 괄호를 스택에서 꺼냄
- 스택이 비었다면 오른쪽 괄호가 먼저 나온 상황이므로 조건 2 위배
- 꺼낸 괄호가 오른쪽 괄호와 짝이 맞지 않으면 조건 3 위배
- 입력 문자열을 끝까지 처리했는데 스택에 괄호가 남아 있으면 괄호의 개수가 맞지 않으므로 조건 1 위배
- 모든 문자를 처리하고 스택이 공백 상태이면 검사 성공
def checkBrackets(statement):
stack = ArrayStack(100)
for ch in statement:
if ch in ('(', '[', '{'):
stack.push(ch)
elif ch in (')', ']', '}'):
if stack.isEmpty():
return False
else:
left = stack.pop()
if (ch == "}" and left != "{") or \
(ch == "]" and left != "[") or \
(ch == ")" and left != "(") :
return False
return stack.isEmpty()
push() - L.append(e)
pop() - L.pop()
size() - len(L)
isEmpty() - len(L)==0
isFull() - False
peek() - L[len(L)-1] or L[-1]
s = list()
msg = input("문자열 입력: ")
for c in msg:
s.append(c)
print("문자열 출력: ", end='')
while len(s) > 0:
print(s.pop(), end='')
print()
import queue
s = queue.LifoQueue(maxsize=20)
push(), pop() - put(), get()
isEmpty(), isFull() - empty(), full()
peek() - 제공하지 않음
s = queue.LifoQueue(maxsize=100)
msg = input("문자열 입력: ")
for c in msg:
s.put(c)
print("문자열 출력: ", end='')
while not s.empty():
print(s.get(), end='')
print()
- 모듈(module): 함수나 객체 또는 클래스를 모아 놓은 파일을 말함
반복 구조의 팩토리얼 함수
def factorial_iter(n):
result = 1
for k in range(2, n+1):
result = result * k
return result
순환 구조의 팩토리얼 함수
def factorial(n):
if n == 1:
return 1 # 순환 호출을 멈추는 부분이 반드시 있어야 함
else:
return n*factorial(n-1) # 문제의 크기는 작아져야 함
[그림]
막대 A에 쌓여 있는 n개의 원판을 모두 C로 옮기는 문제입니다.
단, 다음과 같은 조건을 만족해야합니다.
- 한 번에 하나의 원판만 옮길 수 있습니다.
- 맨 위에 있는 원판만 옮길 수 있습니다.
- 크기가 작은 원판 위에 큰 원판을 쌓을 수 없습니다.
- 중간 막대 B를 임시 막대로 사용할 수 있지만 앞의 조건을 지켜야 합니다.
def hanoi_tower(n, fr, tmp, to):
if (n==1):
print("원판 1: %s --> %s" % (fr, to))
else:
hanoi_tower(n-1, fr, to, tmp)
print("원판 %d: %s --> %s" % (n, fr, to))
hanoi_tower(n-1, tmp, fr, to)
push -> A, D, C, B
pop -> B, C, D, A
def clear(self):
self.top = -1
def display(self):
print(*self.items)
for (i=1; i<10; i++) a[i] = a[(i+1)];
a { b [ ( c + d ) - e ] * f }
0, 9, 18
def printReserve(msg, len):
li = ''
for i in range(len):
li.append(msg[i])
for i in range(len):
print(li.pop(), end='')
instr = "자료구조"
printReserve(instr, len(instr))