정수를 저장하는 스택을 구현한 다음, 입력으로 주어지는 명령을 처리하는 프로그램을 작성하시오.
명령은 총 다섯 가지이다.
push X: 정수 X를 스택에 넣는 연산이다.
pop: 스택에서 가장 위에 있는 정수를 빼고, 그 수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.
size: 스택에 들어있는 정수의 개수를 출력한다.
empty: 스택이 비어있으면 1, 아니면 0을 출력한다.
top: 스택의 가장 위에 있는 정수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.
Input:
14
push 1
push 2
top
size
empty
pop
pop
pop
size
empty
pop
push 3
empty
top
Output:
2
2
0
2
1
-1
0
1
-1
0
3
사실 스택은 STL에도 기본적으로 내장되어 있지만, 다시 한번 자료구조, C++을 공부하는 마음으로 직접 구현해봤다. 스택의 기능들은 별다른 알고리즘이 필요하지는 않아 풀이 자체보다는 어색한 언어를 사용함에 있어서 입출력이나, 문법의 문제가 많았다.
#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdio>
using namespace std;
#define MAXLENGTH = 10000;
class Stack{
private:
int top, MaxSize;
int *stack;
public:
Stack(int size);
int isEmpty();
int isFool();
int topElement();
int pop();
int size();
void push(int element);
};
Stack::Stack(int size){
MaxSize = size;
stack = new int[MaxSize];
top = -1;
}
int Stack::isEmpty(){
if(top == -1) return 1;
return 0;
}
int Stack::isFool(){
if(top == MaxSize-1) return 1;
return 0;
}
int Stack::topElement(){
if(isEmpty() == 1) return -1;
return stack[top];
}
int Stack::size(){
return top+1;
}
int Stack::pop(){
if(isEmpty() == 1) return -1;
return stack[top--];
}
void Stack::push(int element){
if(isFool() != 1) stack[++top] = element;
}
int commandNumber(char* command){
if(!strcmp(command,"pop")) return 1;
if(!strcmp(command,"size")) return 2;
if(!strcmp(command,"empty")) return 3;
if(!strcmp(command,"top")) return 4;
if(!strcmp(command,"push")) return 0;
return -1;
}
int main(){
Stack stack = Stack(MAXLENGTH);
int numberOfCommand;
cin >> numberOfCommand;
fflush(stdin);
char command[20];
int i = 0;
for(int i = 0; i < numberOfCommand; i++){
scanf("%s",command);
switch(commandNumber(command)){
case 0:{
int element;
scanf("%d",&element);
stack.push(element);
break;
}
case 1:{
cout << stack.pop() << endl;
break;
}
case 2:{
cout << stack.size() << endl;
break;
}
case 3:{
cout << stack.isEmpty() << endl;
break;
}
case 4:{
cout << stack.topElement() << endl;
break;
}
default:{}
}
}
return 0;
}
입력을 받는데 있어서 큰 어려움이 있어 계속해서 틀렸다는 메세지를 받았다. 결국 입력문을 수정하다 문제를 풀게 되었다. 처음에는 모든 문자열을 string 타입으로 사용했었는데, C만 했던 나는 char*과 string에서 사용하는 함수의 차이를 잘 구분하기가 어려웠다. gets, fgets, scanf를 차례로 쓰다보니 문제를 해결할 수 있었다. scanf가 공백을 구분해서 입력을 받아온다는 것 이외에는 아직 입출력에서 결과의 차이를 보이는지 잘 모르겠다. 내 IDE에서는 fgets, scanf 모두 정상적으로 작동했다.
입력 받는 로직을 입력문에 맞게 변경하기도 했다. fgets의 경우 push를 염두하여 처음 사용했었는데, push 뒤에 오는 숫자를 한번에 받아오기 위해 사용했었다. 결국 공백 기준으로 자르는 scanf를 사용하여 push일 경우 한번 더 입력을 받아오는 방식으로 입력 로직을 변경했다. 결과적으로는 Command(push)와 숫자(ex.14)를 한꺼번에 받아와서 뒤에 숫자를 따로 분류하는 로직보다 간결했다는 것을 느꼈다.
알고리즘을 생각할 필요가 없다보니, 주어진 조건에 맞게끔 코딩하려 노력했다. command 변수의 길이가 20인 것도 수정해야겠지만, 주어진 조건 안에서 가장 메모리를 적게 사용하게끔 노력했다. 언어가 조금 더 익숙해지면 동적할당을 이용하여 stack 사이즈를 동적으로 할당하는 방식으로 구현해 봐야겠다.
문제
https://www.acmicpc.net/problem/10828
코드
https://github.com/ko-inseoklee/ProblemSolving/blob/main/10828.Stack.cpp