栈 stack

一、栈的介绍
栈(stack)是限定仅在表尾进行插入或删除操作的线性表表。因此,对栈来说表尾端有特殊的意义,称为栈顶(top),相应地,表头称为栈底(bottom)。不含元素的栈为空栈。
假设栈S = (a1,a2,a3,…an),则称a1为栈底元素,an为栈顶元素。栈中的元素按照a1,a2,a3,…an的次序入栈,退栈的第一个元素为栈顶元素。换句话说,栈的修改时按照后进先出的原则进行的即:LIFO。
要想在c++中使用容器栈,需要加上以下的头文件:

#include<iostream>
#include<stack>
using namespace std;

下面是stack的一些成员函数
Member functions

(constructor)
Construct stack (public member function )

empty
Test whether container is empty (public member function )
测试栈是否为空
size
Return size (public member function )
返回栈的大小
top
Access next element (public member function )
获取下一个元素(栈顶的元素)
push
Insert element (public member function )
插入元素
emplace
Construct and insert element (public member function )
构建和插入元素
pop
Remove top element (public member function )
移除栈顶元素
swap
Swap contents (public member function )
交换内容

举例如下:
emplace的例子:

// stack::emplace
#include <iostream>       // std::cin, std::cout
#include <stack>          // std::stack
#include <string>         // std::string, std::getline(string)

int main ()
{
  std::stack<std::string> mystack;

  mystack.emplace ("First sentence");
  mystack.emplace ("Second sentence");

  std::cout << "mystack contains:\n";
  while (!mystack.empty())
  {
    std::cout << mystack.top() << '\n';
    mystack.pop();
  }

  return 0;
}

output:
mystack contains:
Second sentence
First sentence

swap的例子:

// stack::swap
#include <iostream>       // std::cout
#include <stack>          // std::stack

int main ()
{
  std::stack<int> foo,bar;
  foo.push (10); foo.push(20); foo.push(30);
  bar.push (111); bar.push(222);

  foo.swap(bar);

  std::cout << "size of foo: " << foo.size() << '\n';
  std::cout << "size of bar: " << bar.size() << '\n';

  return 0;
}

output:
size of foo: 2
size of bar: 3

二、栈的一些经典例子
1.数制转换
十进制数N与其他的d进制数的转换,其中一个简单的算法基于以下原理:
N = (N div d)*d + N mod d.
代码展示:

#include <iostream>
#include<stack>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<string>
using namespace std;
stack<int> s;
int main()
{
    int n;int d;
    cin>>n>>d;
    while(n!=0){
        int res = n%d;
        s.push(res);
        n = n/d;
    }
    while(!s.empty()){
        cout<<s.top();
        s.pop();
    }
    cout<<endl;
    return 0;
}

2.括号匹配
假设表达式中允许包含三种括号:圆括号和方括号大括号,其嵌套的顺序随意。检查括号是否匹配的方法可用“期待的急迫程度”这个概念来描述。例如考虑下列括号序列:
[([][])]
当计算机接收了第一个括号后,它就期待与其匹配的第八个括号的出现,然而等来的确是第二个括号,此时第一个括号职能暂时靠边,而迫切等待与第二个括号相匹配的的,第七个括号“)”的出现,类似的,因而等来了第三个括号”[“,其期待的急迫程度较第二个括号更加紧迫,则第二个括号要靠边站,依次类推。在算法中,每次读入一个括号:
是右括号,则置于栈顶。
是左括号,要么使栈顶的期待得以解除,要么不合法。
代码展示:

#include <iostream>
#include<stack>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<string>
using namespace std;
stack<char> res;
int main()
{
    //cout<<res.top()<<endl;
    //{[{(([[]]))}]}
    //{([[[]]))}
    string s;
    cin>>s;
    res.push((char)s[0]);
    for(int i=1;i<s.size();i++){
        if((res.top()== '{'&&(char)s[i] == '}')||(res.top()== '('&&(char)s[i] == ')')||(res.top()== '['&&(char)s[i] == ']')){
            res.pop();
        }else{
            res.push(s[i]);
        }

    }

    if(res.empty()){
        cout<<"匹配成功"<<endl;
    }else{
        while(!res.empty()){
        cout<<res.top();
        res.pop();
        }
        cout<<endl;
        cout<<"失败"<<endl;
    }
    return 0;
}

3表达式求值
形如:4+2*(3+5)+6/3 - 3/(1 + 2)
首先我们要规定+,-,*,/,(,)的优先级然后再进行计算。将操作数与操作符分隔开。分别存入一个栈中。
代码展示

#include <iostream>
#include<queue>
#include<algorithm>
#include<stack>
#include<cstring>
#include<string>
#include<stdio.h>
#include<vector>
using namespace std;

stack<int>opd;//操作数
stack<char>opc;//运算符
int priority[100];
char compare(char a,char b){
    if(priority[a]==priority[b]||priority[a]<priority[b])
        return '<';
    if(priority[a]>priority[b])
        return '>';
    if(priority[a]==3&&priority[b]==0)
       return '=';
   if(priority[a]==-1&&priority['b']==-1)return '=';
}
int calculate(int a,int b,char o){
    if(o=='+')return a+b;
    if(o=='-')return a-b;
    if(o=='*')return a*b;
    if(o=='/')return a/b;
}
int main()
{
    //算符优先级
    opc.push('#');
    priority['+'] = priority['-'] = 1;
    priority['*'] = priority['/'] = 2;
    priority['('] = 3;
    priority[')'] = 0;
    priority['#'] = -1;
    string s;
    cin>>s;

    int a,b;
    char o;
    for(int i=0;i<s.size();i++){
        char c = (char)s[i];
        if(c<48||c>57){//十以内的数
            switch(compare(c,opc.top())){
                case '<':{


                     o = opc.top();
                     if(o!='('){
                        opc.pop();
                        b = opd.top();
                        opd.pop();
                        a = opd.top();
                        opd.pop();
                        int res = calculate(a,b,o);
                        //cout<<res<<","<<o<<a<<b<<endl;
                        opd.push(res);
                     }
                     if(c==')'){
                        opc.pop();
                     }else{
                        opc.push(c);
                     }


                    break;
                }

                case '>':{opc.push(c);break;}
                case '=':{opc.pop();break;}
            }
        }else{
            opd.push(c-48);
        }
    }
    while(!opc.empty()){
        o=opc.top();
        if(o=='#')opc.pop();
        else{
            opc.pop();
            b = opd.top();
            opd.pop();
            a = opd.top();
            opd.pop();
            int res = calculate(a,b,o);
            //cout<<res<<","<<o<<a<<b<<endl;
            opd.push(res);
        }
    }
    //3*(2+5)+6/(2+1)+3*(1+3)/4+4*(1+2)#
    cout<<opd.top()<<endl;
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值