Stack

스택은 한쪽 끝에서만 자료를 넣고 뺄 수 있는 자료구조이다.

  • LIFO(Last In First Out) 마지막으로 넣은 것이 가장 먼저 나온다. 즉, 입력순서와 역순의 출력이 필요한 경우에 사용하는 것이 좋다.

    • 에디터에서 되돌리기(undo) 기능

    • 함수 호출 시 복귀주소 기억

연산

설명

push

스택에 자료를 넣는 연산

pop

스택에서 자료를 빼는 연산

top / peak

스택의 가장 위에 있는 자료를 보는 연산

empty

스택이 비어있는지 아닌지를 알아보는 연산

full

스택이 포화상태인지 검사하는 연산

size

스택에 저장되어있는 자료의 개수를 알아보는 연산

스택의 구현

배열

  • 장점 : 1차원 배열로 쉽게 구현할 수 있다.

  • 단점 : 물리적으로 크기가 고정된 배열을 사용하므로 스택의 크기 변경이 어렵다.

연결 리스트

  • 장점 : 크기가 제한되지 않는다.

  • 단점 : 구현이 복잡하고 삽입이나 삭제 시간이 오래걸린다.

구현하는 것보다 짜여져 있는 것을 쓰는게 좋다.

실습

괄호(VPS)

  • 올바른 괄호 문자열의 예시

    • ()

    • (())()

    • ((()))

  • 올바른 괄호 문자열이 아닌 예

    • (()(

    • (()()))

    • (()

스택을 이용해서 괄호 문자열인지 아닌지 알 수 있다. 1. (가 나오면 스택에 넣는다. 2. )가 나오면 스택에서 하나를 빼서 (인지 확인한다.

시간복잡도 O(N^2)

=> 스택을 이용해서 O(N)을 O(1)로 줄일 수 있다.

[예시]

  • (())()

    스택: (

  • (())()

    스택: ((

  • (())()

    스택: (

  • (())()

    스택:

  • (())()

    스택: (

  • (())()

    스택:

모든 과정이 끝난 후 스택이 비어있으므로 올바른 괄호 문자열이다. 만약 모든 과정이 끝난 후 스택이 비어있지 않으면 올바른 괄호 문자열이 아니다.

그러므로 스택에 몇개(size)가 들어가 있는지가 중요하다!

괄호 우선순위

  • 규칙

    1. 대괄호'[]'는 중괄호'{}', 소괄호'()' 안에 올 수 없다.

    2. 중괄호는 소괄호 안에 올 수 없다.

    3. 여는 괄호’(‘,’{‘,’[‘가 나오면 스택에 넣는다.

    4. 닫힌 괄호 ‘)’,’}’,’]’가 나오면 스택에서 뺀다. pop() 이때, 스택의 top이 괄호 짝이 맞아야한다.

    5. 닫힌 괄호가 나왔을 때 스택이 비어있다면 올바른 괄호 문자열이 아니다.

    6. 모든 과정이 끝난 후 스택이 비어있으므로 올바른 괄호 문자열이다. 만약 모든 과정이 끝난 후 스택이 비어있지 않으면 올바른 괄호 문자열이 아니다.

쇠막대기

  • 레이저는 여는 괄호와 닫는 괄호의 인접한(인덱스 중요)()으로 표현한다. 또한, 모든 ()는 반드시 레이저를 표현한다.

  • 쇠막대기의 왼쪽 끝은 (로, 오른쪽 끝은 닫힌 괄호)로 표현한다.

  • ()가 나올 때마다 스택에 들어 있는 (의 개수를 세어준다.

  • )가 나왔을 때는 레이저인지 쇠막대기 인지 구분을 해준다.

  • 레이저는 항상 붙어진 상태로 나오므로 스택의 (의 인덱스와 1차이가 나는지 확인해야한다.

에디터

  • 커서는 문장의 맨 앞, 맨 뒤, 중간 임의의 곳에 위차할 수 있다.

  • L : 커서를 왼쪽으로 한칸 옮김

  • D : 커서를 오른쪽으로 한칸 옮김

  • B : 커서 왼쪽에 있는 문자를 삭제

  • P $ : $라는 문자를 커서 오른쪽에 추가

  • 커서를 기준으로 왼쪽 스택오른쪽 스택으로 나눠서 문제를 풀 수 있다.

  • L 왼쪽으로 옮김

  • D 오른쪽으로 옮김

  • B 왼쪽 문자 삭제

  • P$ $를 커서 왼쪽에 추가하고 커서는 $의 오른쪽에 위치

O(N^2)에서 스택을 사용하면 O(N)으로 시간복잡도가 줄어든다.

후위 표기식

수식의 표기방법

  • 전위 표기법 : 연산자를 피연산자 앞에 표기하는 방법 (+AB)

  • 중위 표기법 : 연산자를 피연산자 중간에 표기하는 방법 (A+B)

  • 후위표기법 : 연산자를 피연산자 뒤에 표기하는 방법 (AB+)

수식을 왼쪽에서 오른쪽으로 스캔하여

  1. 피연산자이면 스택에 저장

  2. 연산자이면 필요한 수만큼의 피연산자를 스택에서 pop

  3. 연산의 결과를 다시 스택에 저장

구현시 연산자가 나왔을 때 pop을 두번할 수 있는지와 같은 조건을 따져야한다.

중위 표기식 → 후위 표기식

  1. 수식의 각 연산자에 대해서 우선순위에 따라 괄호를 사용하여 다시 표현한다. ((A*B)-(C/D))

  2. 각 연산자를 그에 대응하는 오른쪽 괄호의 뒤로 이동시킨다.((A B)* (C D)/)-

  3. 괄호 제거 AB*CD/-

알고리즘 개요

  1. 왼쪽 괄호를 만나면 무시

  2. 피연산자를 만나면 출력

  3. 연산자를 만나면 스택에 삽입

  4. 오른쪽 괄호를 만나면 스택 pop

  5. 수식이 끝나면 스택이 공백이 될 때까지 pop

Last updated

Was this helpful?