stack in C++STL library

 


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 description
stack()                                                                                  constructs an empty stack
empty()                                                                          detects whether the stack is empty
size()                                                                             returns the number of elements in the stack
top()                                                                                  returns a reference to the top element of the stack
push()                                                                          pushes the element val into the stack
pop()   pops the last element in the stack                                                                        
swap()                                                                        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();
 */

Guess you like

Origin blog.csdn.net/qq_67458830/article/details/132025786