Article directory
-
Introduction to stack
-
Common interfaces of stack
-
Simulation implementation of stack
-
Related OJ questions about stacks
1. Introduction to stack
- 1. Stack is a container adapter that is specially used in contexts with last-in-first-out operations. Its deletion can only insert and extract elements from one end of the container.
- 2. Stack is implemented as a container adapter. A container adapter encapsulates a specific class as its underlying container and provides a set of specific member functions to access its elements. It uses a specific class as its underlying, element-specific container. The tail (that is, the top of the stack) is pushed and popped.
- 3. The underlying container of the stack can be any standard container class template or some other specific container classes. These container classes should support the following operations:
- empty: empty operation
- back: Get the tail element operation
- push_back: tail insertion element operation
- pop_back: tail deletion element operation
- 4. The standard containers vector, deque, and list all meet these requirements. By default, if no specific underlying container is specified for the stack, deque is used by default.
2. Common interfaces of stack
Function description Interface descriptionstack() constructs an empty stackempty() detects whether the stack is emptysize() returns the number of elements in the stacktop() returns a reference to the top element of the stackpush() pushes the element val into the stackpop() pops the last element in the stackswap() exchanges the contents of two containers
Related interface demonstration:
#include <iostream>
#include <stack>
int main()
{
std::stack<int> st;
st.push(1);
st.push(2);
st.push(3);
while (!st.empty()) {
std::cout << st.top() << " ";
st.pop();
}
return 0;
}
3. Simulation implementation of stack
#pragma once
namespace Stack
{
//这里默认是采用deque这种适配器来模拟栈
template<class T,class Contain=std::deque<T>>
class stack
{
public:
/*
stack()//这里不需要显示写构造函数,因为是自定义类型,直接调用默认构造函数就行
{}
*/
bool empty()
{
return _con.empty();
}
size_t size()const
{
return _con.size();
}
const T& top()const
{
return _con.back();
}
void push(const T& val)
{
_con.push_back(val);
}
void pop()
{
_con.pop_back();
}
void swap(stack<T, Contain>& st)
{
std::swap(_con, st._con);
}
private:
Contain _con;
};
}
4. Related OJ questions about stacks
1. Minimum stack OJ link
The idea of this question : Setting up an auxiliary stack and a minimum stack can solve the problem.
class MinStack {
private:
stack<int> minST;
stack<int> tmpST;
public:
MinStack() {
}
void push(int val) {
tmpST.push(val);
if(minST.empty()||minST.top()>=val)
minST.push(val);
}
void pop() {
if(tmpST.top()==minST.top()){
tmpST.pop();
minST.pop();
}
else
tmpST.pop();
}
int top() {
return tmpST.top();
}
int getMin() {
return minST.top();
}
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(val);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->getMin();
*/
2. Stack push and pop sequence OJ link
Ideas for this question: Use of this question
class Solution {
public:
bool IsPopOrder(vector<int> pushV,vector<int> popV) {
if(pushV.size()!=popV.size())//前言如果不满足这两个条件则直接返回false
return false;
if(pushV.empty()||popV.empty())
return false;
stack<int> ST;//创建出来一个栈
int i,j=0;
for(i=0;i<pushV.size();i++)//将压栈数组插入到栈中
{
ST.push(pushV[i]);
while(!ST.empty()&&ST.top()==popV[j])//循环进行遍历操作,如果此时的popV[j]==ST.top(),则出栈
{
ST.pop();
j++;
}
}
if(!ST.empty())
return false;
return true;
}
};
3. Reverse Polish expression evaluation OJ link
Idea for this question: Since this question is a suffix expression, the calculation starts from left to right using operators and then the result is pushed onto the stack.
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<string> stk;
for(auto&str:tokens){
if(str=="+"){
int x=stoi(stk.top());
stk.pop();
int y=stoi(stk.top());
stk.pop();
auto sum=[](int x,int y){
return x+y;
};
stk.push(to_string(sum(x,y)));
}
else if(str=="-"){
int x=stoi(stk.top());
stk.pop();
int y=stoi(stk.top());
stk.pop();
auto sub=[](int x,int y){
return y-x;
};
stk.push(to_string(sub(x,y)));
}
else if(str=="*"){
int x=stoi(stk.top());
stk.pop();
int y=stoi(stk.top());
stk.pop();
auto mul=[](int x,int y){
return x*y;
};
stk.push(to_string(mul(x,y)));
}
else if(str=="/"){
int x=stoi(stk.top());
stk.pop();
int y=stoi(stk.top());
stk.pop();
auto div=[](int x,int y){
return y/x;
};
stk.push(to_string(div(x,y)));
}
else {
stk.push(str);
}
}
return stoi(stk.top());
}
};
4. Use stack to implement queue OJ link
The idea of this question: use two stacks, one stack is used to output data, and the other is used to input data.
class MyQueue {
//定义两个栈一个栈用来出数据,一个栈用来插入数据
private:
stack<int> PushST;
stack<int> PopST;
public:
MyQueue() {
}
//将数据放入插入数据的栈中
void push(int x) {
PushST.push(x);
}
//如果此时出数据的栈空为空时则将数据导入出数据的栈中
int pop() {
if(PopST.empty())
{
while(!PushST.empty())
{
PopST.push(PushST.top());
PushST.pop();
}
}
int ret=PopST.top();
PopST.pop();
return ret;
}
int peek() {
if(PopST.empty())
{ while(!PushST.empty())
{
PopST.push(PushST.top());
PushST.pop();
}
}
return PopST.top();
}
bool empty() {
return PushST.empty()&&PopST.empty();
}
};
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue* obj = new MyQueue();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->peek();
* bool param_4 = obj->empty();
*/