사실 C++에서는 <stack>으로 스택을 사용할 수 있어서 직접 구현할 필요는 없다. 그런데 스택 라이브러리를 사용할 수 없는 일이 발생한다면? 기본적인 구현 방법은 알아야하지 않겠는가. 클래스와 템플릿을 이용하여 구현해보자.
백준의 10828. 스택 문제를 이용하였다.
문제
https://www.acmicpc.net/problem/10828
풀이
스택의 생성부터 각 기능들의 구현들을 차근차근 설명해나가겠다.
1. 스택 선언
template <typename T>
class Stack{
private :
int Topidx; // top의 인덱스
T* ptr; // 저장 공간 설정
public :
Stack(int size); // 생성자
~Stack(); // 소멸자
T Pop(); // stack.pop()
void Push(const T& val); // stack.push()
int Empty(); // stack.empty()
int Top(); // stack.top()
int Size(); // stack.size()
};
일단 문제에선 int형만 취급하지만, 사실 스택은 어떤 타입이든 저장할 수 있다. 따라서 template로 임의의 타입을 저장할 수 있도록 설정해준다.2. 스택 생성
template <typename T>
Stack::Stack(int size){
Topidx = -1; // 배열은 인덱스가 0부터 이므로 -1로 초기 설정
ptr = new T[size]; // 저장공간 선언
};
배열은 index가 0부터 시작하므로 -1로 초기화 해줘야 뒤에 push를 할 때 Topidx++ 연산을 처음부터 적용할 수 있다. 즉 예외처리를 해줄 필요가 없다.3. 스택 소멸
template <typename T>
Stack::~Stack(){
delete ptr;
};
문제와 관계 없지만 구현해보았다.4. 스택 - push
template <typename T>
void Stack::Push(const T& val){
ptr[++Topidx] = val; // 생성자에서 -1로 초기설정해 준 이유. 예외 없이 인덱스를 더해줌
};
기본적으로 -1부터 시작해야 index 관련 연산을 할 때 예외가 없음5. 스택 - pop
template <typename T>
T Stack::Pop(){
if(Topidx < 0) return -1; // Topidx < 0 --> Topidx = -1 --> 스택이 비어있음
else return ptr[Topidx--]; // 비어있지 않으면 제일 윗부분을 빼고 뺀 정수를 출력
};
6. 스택 - empty
template <typename T>
int Stack::Empty(){
if(Topidx < 0) return 1; // 비어있으면 1
else return 0; // 그렇지 않으면 0
};
7. 스택 - top
template <typename T>
int Stack::Top(){
if(Topidx < 0) return -1; // 비어있으면 -1
else return ptr[Topidx]; // 그렇지 않으면 제일 위의 정수 출력
};
8. 스택 - size
template <typename T>
int Stack::Size(){
if(Topidx < 0) return 0; // 비어있으면 0
else return Topidx + 1; // 그렇지 않으면 가장 위의 인덱스 + 1 (예를 들어 인덱스가 0이면 1개인거니까)
};
소스코드
//
// Stack.cpp
// test
//
// Created by 신기열 on 09/06/2019.
// Copyright © 2019 신기열. All rights reserved.
//
#include <stdio.h>
#include <iostream>
using namespace std;
template <typename T>
class Stack{
private :
int Topidx; // top의 인덱스
T* ptr; // 저장공간 설정
public :
Stack(int size); // 생성자
~Stack(); // 소멸자
T Pop(); // stack.pop()
void Push(const T& val); // stack.push()
int Empty(); // stack.empty()
int Top(); // stack.top()
int Size(); // stack.size()
};
template <typename T>
Stack::Stack(int size){
Topidx = -1; // 배열은 인덱스가 0부터이므로 -1로 초기 설정
ptr = new T[size]; // 저장공간 선언
};
template <typename T>
Stack::~Stack(){
delete ptr;
};
template <typename T>
void Stack::Push(const T& val){
ptr[++Topidx] = val; // 생성자에서 -1로 초기설정해 준 이유. 예외 없이 인덱스를 더해줌
};
template <typename T>
T Stack::Pop(){
if(Topidx < 0) return -1; // Topidx < 0 --> Topidx = -1 --> 스택이 비어있음
else return ptr[Topidx--]; // 비어있지 않으면 제일 윗부분을 빼고 뺀 정수를 출력
};
template <typename T>
int Stack::Empty(){
if(Topidx < 0) return 1; // 비어있으면 1
else return 0; // 그렇지 않으면 0
};
template <typename T>
int Stack::Top(){
if(Topidx < 0) return -1; // 비어있으면 -1
else return ptr[Topidx]; // 그렇지 않으면 제일 위의 정수 출력
};
template <typename T>
int Stack::Size(){
if(Topidx < 0) return 0; // 비어있으면 0
else return Topidx + 1; // 그렇지 않으면 가장 위의 인덱스 + 1 (예를 들어 인덱스가 0이면 1개인거니까)
};
int main(){
int n, j = 0;
cin >> n;
Stack<int> S(10000);
int stored[10000];
string s[10001];
for(int i = 0; i < n; i++){
cin >> s[i];
if(s[i].compare("push") == 0){
cin >> stored[j];
j++;
}
}
j = 0;
for(int i = 0; i < n; i++){
if(s[i].compare("top") == 0){
cout << S.Top() << '\n';
}
else if(s[i].compare("empty") == 0){
cout << S.Empty() << '\n';
}
else if(s[i].compare("pop") == 0){
cout << S.Pop() << '\n';
}
else if(s[i].compare("size") == 0){
cout << S.Size() << '\n';
}
else{
S.Push(stored[j]);
j++;
}
}
}
댓글
댓글 쓰기