应用

栈的应用

验证括号的正确性

  题目很简单就是输入一串字符,判断字符中的括号是否合法。直接上代码:

#include <iostream>
#include <string.h>
using namespace std;

typedef char ElemType;
#define MAXSIZE 100

typedef struct Stack
{
    ElemType data[MAXSIZE];
    int top;
}Stack;

void InitStack(Stack& S) {
    S.top = -1;
}

bool StackEmpty(Stack S) {
    if (S.top == -1) {
        return true;
    }
    return false;
}

bool Push(Stack& S, ElemType x) {
    if (S.top == MAXSIZE - 1) {
        return false;
    }
    S.top++;
    S.data[S.top] = x;
    return true;
}
bool Pop(Stack& S, ElemType& x) {
    if (S.top == -1) {
        return false;
    }
    x = S.data[S.top];
    S.top--;
    return true;
}

ElemType GetTop(Stack S) {
    return S.data[S.top];
}

int main() {
    Stack S;
    InitStack(S);
    string str;
    cin >> str;
    //flag标志状态 true为括号匹配,false为不匹配
    bool flag = true;
    for (int i = 0; i < str.size(); i++) {
        //元素若为{,(,[则入栈
        if ((str[i] == '{') || (str[i] == '[') || (str[i] == '(')) {
            Push(S, str[i]);
        }//元素若为},),]则出栈 赋值给right
        if ((str[i] == '}') || (str[i] == ']') || (str[i] == ')')) {
            if ((str[i] == '}' && GetTop(S) == '{') 
                || (str[i] == ']' && GetTop(S) == '[') 
                || (str[i] == ')' && GetTop(S) == '(')) {
                char top = Pop(S, top);
                continue;
            }
            else {
                Push(S, str[i]);
            }
        }
    }
    if (S.top != -1) {    //当栈不为空时
        flag = false;
    }
    if (flag == false) {
        cout << "括号不匹配!" << endl;
    }
    else cout << "括号匹配!" << endl;
    system("pause");
    return 0;
}

  实验结果:

表达式求值

  要求一个表达式的结果,例如 9 +(3 - 1) * 3 + 1 ,我们可以直接算出来,但是计算机不会,计算机一般将这种表达式转换成后缀表达式,运算符在操作数后面,并且运算也是根据优先级排列好的,没有括号,利于计算机的计算,如上述表达式转换为后缀表示式为:

9 3 1 - 3 * 10 + ,但是我们现在要实现的是中缀表达式的求值。计算思路:

  • 使用两个栈,stack0用于存储操作数,stack1用于存储操作符

  • 从左往右扫描,遇到操作数入栈stack0

  • 遇到操作符时,如果优先级低于或等于栈顶操作符优先级,则从stack0弹出两个元素进行计算,并压入stack0,继续与栈顶操作符的比较优先级

  • 如果遇到操作符高于栈顶操作符优先级,则直接入栈stack1

  • 遇到左括号,直接入栈stack1,遇到右括号,则直接出栈并计算,直到遇到左括号

//算符优先法
#include<iostream>
#include<cstring>
#include<stack>
using namespace std;  
const int maxn=110; 
char priority[7][7]={ 
    {'>','>','<','<','<','>','>'},  
    {'>','>','<','<','<','>','>'},  
    {'>','>','>','>','<','>','>'},  
    {'>','>','>','>','<','>','>'},  
    {'<','<','<','<','<','=','0'},   // 此行"("=")"表示左右括号相遇,括号内运算已完成 
    {'>','>','>','>','0','>','>'},  
    {'<','<','<','<','<','0','='}    // "=" 表示整个表达式求值完毕 
    };                               //  "0"表示不可能出现这种情况 ( 语法错误 ) 

//Precede 用于判断运算符栈栈顶运算符 a1 与读入运算符 a2 之间的优先关系函数 
char Procede(char a,char b){   // 建立 pre[][] 到 运算符间的映射关系 
    int i,j;  
    switch(a){  
        case'+':i=0;break;  
        case'-':i=1;break;  
        case'*':i=2;break;  
        case'/':i=3;break;  
        case'(':i=4;break;  
        case')':i=5;break;  
        case'#':i=6;break;   // # 是表达式的结束符 
    }  
    switch(b){  
        case'+':j=0;break;  
        case'-':j=1;break;  
        case'*':j=2;break;  
        case'/':j=3;break;  
        case'(':j=4;break;  
        case')':j=5;break;  
        case'#':j=6;break;  
    }  
    return priority[i][j];  
}

int Operate(int m,int n,char x){  
    if(x=='+')  
    return m+n;  
    if(x=='-')  
    return n-m;  
    if(x=='*')  
    return m*n;  
    if(x=='/')  
    return n/m;  
}  
// EvaluuateExpression-reduced
int main(){
    stack <int> OPND;  // Operand stack
    stack <char> OPTR;  // Operator stack
    OPTR.push('#');//
    char ss[2]="#";//尾部有\0 
    char s[maxn];
    cin>>s;
    strcat(s,ss);// 运算式尾部加 "#"--结束运算符 
    char c=s[0];
    int k=1;
    while(c!='#'||OPTR.top()!='#'){  //表达式未读完或者运算未完 
        int y=0;  
        if(c>='0'&&c<='9'){    
            while(c>='0'&&c<='9'){  // 读入连续的数字 
                y=y*10+(c-'0');  
                c=s[k++];  
            }  
            OPND.push(y);  // 把读进的数字入数字栈 
        }
        else{
            switch(Procede(OPTR.top(),c))  
            {  
                case'<':  //栈顶元素优先权低 
                    OPTR.push(c);  
                    c=s[k++];  
                    break;  
                case'=':  
                    OPTR.pop();  // 脱括号 
                    c=s[k++];  // 读入下一个字符 
                    break;  
                case'>':  //退栈并将运算结果入栈 
                    char x=OPTR.top();OPTR.pop();  
                    int m=OPND.top();OPND.pop();  
                    int n=OPND.top();OPND.pop();  
                    OPND.push(Operate(m,n,x));  
                    break;    
            } 
        }
    }
    cout<<OPND.top();
    return 0;
}

  实验结果:

队列的应用

层次遍历

  利用队列存储每一层的结点,再存储到数组中,很容易理解。下面是套路:

vector<vector<int>> levelOrder(TreeNode* root) {
    queue<TreeNode*> q;
    if (root != nullptr)   q.push(root);
    vector<vector<int>> res;
    while (!q.empty()) {
        int sz = q.size();
        vector<int> temp;
        for (int i = 0; i < sz; i++) {
            TreeNode* cur = q.front();
            q.pop();
            temp.push_back(cur->val);
            if (cur->left != nullptr)
                q.push(cur->left);
            if (cur->right != nullptr)
                q.push(cur->right);
        }
        res.push_back(temp);
    }
    return res;
}

队列在计算机系统中的应用

  一、解决主机与外部设备之间速度不匹配的问题。

  二、解决由多用户引起的资源竞争问题。

Last updated