스택(Stack)
- 스택은 한쪽 끝에서만 자료를 넣고 뺄 수 있는 자료구조
- 마지막으로 넣은 것이 가장 먼저 나오기 때문에 Last In Frist Out (LIFO) 라고도 한다.
push: 스택에 자료를 넣는 연산pop: 스택에서 자료를 빼는 연산top: 스택의 가장 위에 있는 자료를 보는 연산empty: 스택이 비어있는지 아닌지를 알아보는 연산size: 스택에 저장되어있는 자료의 개수를 알아보는 연산
일차원 배열 하나로 구현할 수 있다 .
1int stack[10000];2int size = 0;
1. 스택 - 10828
python
1"""2파이썬은 따로 stack 구조를 제공하지 않는다.3기본 클래스 list를 이용하여 stack을 표현할 수 있다.4"""5import sys67# 입력을 빠르게 받기 위해 sys.stdin.readline을 input으로 사용8input = sys.stdin.readline910n = int(input()) # 정수 n을 입력받습니다. 이것은 명령의 개수를 의미11stack = [] # 스택을 생성, 스택은 나중에 사용될 리스트1213for _ in range(n): # n번 반복14s = input().split() # 공백을 기준으로 문자열을 분리15cmd = s[0] # 리스트 s의 첫 번째 요소를 명령어로 설정1617if cmd == "push":18num = int(s[1]) # 문자열을 정수로 변환하여 숫자를 얻음19stack.append(num) # 스택에 숫자를 추가2021elif cmd == "top":22# 스택이 있으면, 가장 위에 있는 숫자를 출력23if stack:24print(stack[-1])25# 스택이 비어있으면, -1 출력26else:27print(-1)2829# 스택의 크기(길이)를 출력30elif cmd == "size":31print(len(stack))3233# 스택이 비어있으면 1, 아니면 0을 출력34elif cmd == "empty":35print(0 if stack else 1)3637elif cmd == "pop":38# 스택이 있으면, 가장 위에 있는 숫자를 꺼내고 출력39if stack:40print(stack.pop())41# 스택이 비어있으면, -1을 출력42else:43print(-1)
2. 단어 뒤집기 - 9093
- 단어 뒤집기 📚 https://www.acmicpc.net/problem/9093
python
1"""2N개의 글자를 스택에 넣었다가 빼면 순서가 역순이 된다.3알파벳을 스택에 넣고, 공백이나 문자열의 끝이면 스택에서 모두 빼내서 역순을 만든다.45📌 [::-1] : 리스트를 처음부터 끝까지 거꾸로 스텝하라는 의미6-> 파이썬 리스트에서 슬라이싱을 사용하여 역순으로 된 리스트를 생성7📌 join() : 문자열 리스트의 각 요소들을 하나의 문자열로 이어붙이는 역할8"""9import sys1011input = sys.stdin.readline1213TEST_CASE = int(input())141516for _ in range(TEST_CASE):17inputSentence = input() # 한 줄을 읽어들여 변수에 저장18stack = []1920# 문자열 inputSentence에 대해 한 문자씩 반복21for charactor in inputSentence:22if charactor == " " or charactor == "\n":23# stack에 저장된 문자들을 역순으로 이어붙여서 출력하고, 마지막의 개행 문자를 제거24print("".join(stack[::-1]), end="")25stack.clear()2627# 공백(' ') 또는 개행 문자('\n')를 출력28print(charactor, end="")29# 문자 ch가 공백 또는 개행 문자가 아니라면, stack에 문자를 추가30else:31stack.append(charactor)
3. 괄호 - 9012
python
1def getIsParentheses(s):2count = 0 # 괄호 쌍을 유지하기 위한 카운트 변수 초기화34for ch in s:5# 여는 괄호일 경우 카운트 증가 (괄호 쌍 시작)6if ch == "(":7count += 18# 닫는 괄호일 경우 카운트 감소 (괄호 쌍 끝)9else:10count -= 111# 중간에 닫는 괄호가 더 많을 경우12if count < 0:13return "NO"14# 모든 괄호가 쌍을 이루었을 경우15if count == 0:16return "YES"17# 괄호 쌍이 다 맞지 않는 경우18else:19return "NO"202122TEST_CASE = int(input())2324for _ in range(TEST_CASE):25print(getIsParentheses(input()))
4. 스택 수열 - 1874
python
1"""2스택에 수를 push 할 때는 반드시 오름차순으로만 push할 수 있다.34e.g., 8을 push해야 한다면 앞의 1~7까지를 모두 push하고 8을 push할 수 있다.5그리고 스택을 쌓다가 필요한 타이밍에 pop을 하게 되는데, 이 pop을 한 수들을 쭉 나열했을 때,6N줄에 걸쳐 입력한 수열과 같아야 한다.78e.g. N=8이고 다음줄부터 4, 3, 6, 8, 7, 5, 2, 1을 입력한 상황을 보면9스택을 쌓다가 중간에 한번씩 pop을 한 데이터들을 나열한 순서도 4, 3, 6, 8, 7, 5, 2, 1이 되어야 한다1011처음으로 4를 입력했다.12즉, 내가 첫 번째로 pop한 숫자가 4가 되어야 한다. 그러기 위해서는 1,2,3,4가 이미 스택안에 있어야 한다.13그래서 입력한 수를 만날 때 까지는 계속 push를 해서 1,2,3,4가 스택에 있도록 해야한다1415그리고 나서 4를 꺼내 스택은 현재 1,2,3인 상황이다.16그 다음으로 3이 주어졌기 때문에 push없이 현재 스택에서 pop을 하면 된다. 그리고 스택은 1,2가 된다.17그다음 입력으로 6이 주어졌기 때문에, 다시 6을 만날 때 까지 이전의 숫자들을 push 해준다. ( 즉 5, 6 push )1819----------20이 때, stack에서 pop할 숫자(TOP)가 입력한 숫자가 아닐 경우(작을 경우) 정답을 완성할 수 없다.21왜냐하면 TOP 값이 입력한 숫자보다 크면, 입력한 수를 꺼내기 위해 계속 POP을 해야 하기 때문에22그 과정에서 POP한 수들의 수열이 정답과 일치하지 않게 되기 때문이다.2324e.g. 1, 2, 5, 3, 4가 입력으로 주어졌다고 하자.251을 입력했을 때 스택은 [1] -> pop -> 1262을 입력했을 때 스택은 [2] -> pop -> 2275을 입력했을 때 스택은 [3, 4, 5] -> pop -> 5283을 입력했을 때 스택은 [3, 4] -> pop -> 4 가 된다.293이 먼저 나와야 하는데 4가 먼저 나와버린 것이다30"""31import sys3233n = int(input())34stack = []35result = []3637# n개의 숫자를 입력받아 수열 리스트에 저장38progression = [int(input()) for _ in range(n)]3940# 스택에 push할 오름차순 자연수, 맨 처음에 들어간 것이 없으니 0으로 초기화41currentNum = 04243for el in progression:44# 입력된 숫자가 현재 최댓값보다 큰 경우45if el > currentNum:46# el와 같아질 때까지, currentNum의 값을 1씩 올리면서 push를 반복, '+' 기호를 추가하여 push 동작을 표시47while el > currentNum:48currentNum += 149stack.append(currentNum)50result += ["+"]5152# el와 같아져서 반복이 끝난 후, 스택에서 값을 제거하고, '-' 기호를 추가하여 pop 동작을 표시53stack.pop()54result += ["-"]5556# 입력된 숫자가 현재 최댓값보다 작거나 같은 경우57else:58# 스택의 맨 위 값과 입력된 숫자가 다른 경우 'NO' 출력59if stack[-1] != el:60print("NO")61sys.exit(0) # 프로그램 종료62# 스택의 맨 위 값과 입력된 숫자가 같은 경우, 스택에서 값을 제거하여 pop 동작 표시63stack.pop()64result += ["-"]6566# 결과 리스트의 내용을 개행문자와 함께 출력67print("\n".join(result) + "\n")
5. 에디터 - 1406
python
1"""2'L'은 커서를 왼쪽으로 옮김3'D'는 커서를 오른쪽으로 옮김4'P'는 커서 왼쪽에 문자를 추가5'B'는 커서 왼쪽에 문자를 삭제6모든 명령어를 수행하고 난 후 편집기에 입력되어 있는 문자열을 구하는 프로그램78커서를 기준으로 커서의 왼쪽 스택(left)와 오른쪽 스택(right)로 나눠서 문제를 풀 수 있다.9e.g. abc | xyz (|는 커서를 의미)10"""11import sys1213input = sys.stdin.readline1415left = list(input().strip()) # 왼쪽 문자열 초기화16right = [] # 오른쪽 문자열을 위한 빈 리스트 생성1718M = int(input()) # 수행할 명령어 개수 입력1920for _ in range(M):21line = input().strip().split() # 공백을 기준으로 입력을 나눠 리스트에 저장22command = line[0] # 명령어의 첫 번째 요소 (어떤 작업을 할지)2324if command == "L":25# 왼쪽 문자열에 남아있는 문자가 있는 경우, 왼쪽 문자열의 마지막 문자를 오른쪽 문자열로 이동26if left:27right.append(left.pop())28elif command == "D":29# 오른쪽 문자열에 남아있는 문자가 있는 경우, 오른쪽 문자열의 마지막 문자를 왼쪽 문자열로 이동30if right:31left.append(right.pop())32elif command == "P":33# 두 번째 요소로 주어진 문자를 왼쪽 문자열에 추가34left.append(line[1])35elif command == "B":36# 왼쪽 문자열에 남아있는 문자가 있는 경우, 왼쪽 문자열의 마지막 문자 삭제37if left:38left.pop()3940left += right[::-1] # 남은 문자열을 모두 왼쪽 문자열에 추가 (오른쪽 문자열을 뒤집어서)4142print("".join(left)) # 왼쪽 문자열을 하나의 문자열로 합쳐서 출력