栈实现表达式求值,队列应用

发布时间 2023-11-23 21:44:58作者: 艾鑫4646

1.

 

 

2.

 

 

 

一、  源程序

 1.

#include<bits/stdc++.h>

using namespace std;

const int N=100010;

//去掉空格

string split(string s){

    string ss;

    for(int i=0;i<s.size();i++){

        if(s[i]==32) continue;

        ss+=char(s[i]);

    }

    return ss;

}

//判断是否缺括号

bool check1(string s){

    int cnt=0;

    for(int i=0;i<s.size();i++){

        if(s[i]=='(') cnt++;

        else if(s[i]==')') cnt--;

    }

    return  cnt==0;

}

//判断运算符和数的合理性

bool check2(string s){

    for(int i=0;i<s.size();i++){

        if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/'){

            if(i==0||i==s.size()-1||i&&(s[i-1]=='+'||s[i-1]=='-'||s[i-1]=='*'||s[i-1]=='/')){

                return 0;

            }

        }

    }

    return 1;

}

 

int pri(char ch){return ch=='*'||ch=='/'?2:1;}

char ch[N];

int cnt;

string suan(string s){

    string ss;

    for(int i=0;i<s.size();i++){

        if(s[i]>='0'&&s[i]<='9'){

            ss+=char(s[i]);

        }else{

            if(s[i]=='('){

                ch[cnt++]='(';

            }else if(s[i]==')'){

                while(ch[cnt-1]!='('){

                    ss+=ch[--cnt];

                }

                cnt--;

            }else{

                char c=char(s[i]);

                if(cnt>0&&pri(c)<=pri(ch[cnt-1])){

                    while(cnt>0&&ch[cnt-1]!='('&&pri(c)<=pri(ch[cnt-1])){

                        ss+=ch[--cnt];

                    }

                }

                ch[cnt++]=c;

            }

        }

    }

    while(cnt>0){

        ss+=ch[--cnt];

    }

    return ss;

}

 

int op(int x,int y,char ch){

    if(ch=='+') return x+y;

    else if(ch=='-') return x-y;

    else if(ch=='*') return x*y;

    else return x/y;

}

int a[N],ct;

int op(string s){

    for(int i=0;i<s.size();i++){

        if(s[i]>='0'&&s[i]<='9'){

            a[ct++]=s[i]-48;

        }

        else{

            int x=a[ct-2],y=a[ct-1];

            ct-=2;

            a[ct++]=op(x,y,char(s[i]));

        }

    }

    return a[0];

}

 

int main(){

    string s;

    getline(cin,s);

    

    s=split(s);

 

    if(!check1(s)){

        cout<<"ERROR:缺少括号";

        return 0;

    }

     if(!check2(s)){

        cout<<"ERROR:表达式缺操作数";

        return 0;

    }

    

    string ss=suan(s);

    cout<<ss<<endl;

    

    cout<<op(ss);

    

    return 0;

}

2.#include<bits/stdc++.h>

using namespace std;

 

int main() {

    //VIP存储队列

    list< string> listVIP;

    //normal存储队列

    list< string> listNormal;

    string print;

     string name;

     string ID;

    int M;

     cin >> M;

 

    while (M > 0) {

        M--;

        cin >> print;

 

        if (print == "OUT") {

             cin >> ID;

            if (ID == "V") {

                listVIP.pop_front();

            } else {

                listNormal.pop_front();

            }

        } else {

            cin >> name >> ID;

            if (ID == "V") {

                listVIP.push_back(name);

            } else {

                listNormal.push_back(name);

            }

        }

    }

 

    for (const auto &s : listVIP) {

         cout << s <<  endl;

    }

 

    for (const auto &s : listNormal) {

         cout << s << endl;

    }

 

    return 0;

}

二、  个人体会(此部分与拼题a上主观题提交应一致)

 

 7-2 栈实现表达式求值

1.问题是关于后缀表达式的生成和计算。我们需要将中缀表达式转换为后缀表达式,然后计算后缀表达式的值。这需要我们正确地处理运算符的优先级和括号的使用。

2.先创建一个空栈和一个空输出队列,从左到右扫描中缀表达式。

如果当前字符是一个数字,将其加入输出队列。

如果当前字符是一个左括号,将其压入栈。

如果当前字符是一个右括号,则将栈元素弹出并加入输出队列,直到遇到左括号为止。左括号只弹出而不加入输出队列。

如果当前字符是一个运算符(、+-*/),o1,将其与栈顶运算符o2比较。如果o1优先级大于o2,或者o1是左括号,则将o1压入栈。否则,从栈弹出元素并加入输出队列,直到遇到优先级大于或等于o1的运算符或者左括号为止。然后将o1压入栈。

重复以上步骤直到扫描完整个中缀表达式。

将栈中所有元素弹出并加入输出队列。

输出队列中的元素就是转换后的后缀表达式。

3.实验设计思路

1)判断表达式是否正确,括号缺失的表达式,输出"ERROR:缺少括号"。输入两个除括号外运算符连续的表达式,输出"ERROR:表达式缺操作数"

2)实现中缀表达式到后缀表达式的转换。遍历中缀表达式中的每个字符,若为数字则直接加入后缀表达式中,若为左括号则压入栈中,若为右括号则将栈中的运算符弹出并加入后缀表达式中,直到遇到左括号为止,左括号只弹出不加入后缀表达式。若为运算符,则与栈顶运算符比较优先级,若优先级大于栈顶运算符或为左括号,则将当前运算符压入栈中;否则从栈中弹出元素并加入后缀表达式,直到遇到优先级大于或等于当前运算符的运算符或左括号为止。

3)计算后缀表达式的值。从左到右遍历后缀表达式中的每个字符,若为数字则将其转换为整型并加入结果中,若为运算符则从栈中弹出两个操作数并计算其值,将结果加入结果中。

4)输出后缀表达式和结果。

实验后的感想:


首先,更加熟悉了栈的使用,通过使用栈,我们可以有效地处理括号和运算符优先级的问题,这是中缀表达式直接转换为后缀表达式所无法比拟的。

其次,我对表达式转换的过程有了更深入的理解。从中缀表达式到后缀表达式的转换是一个复杂的过程,通过实现这个转换,我增强了自己的编程技能,并对计算机科学原理有了更好的理解。

最后,我对如何设计和实现一个有效的后缀表达式有了更清晰的认识。后缀表达式是一种非常有效的计算方式,能够简化复杂的数学运算。 通过这个实验,我对如何设计和实现这样的计算器有了更清晰的认识。

总的来说,这个实验让我对计算机科学有了更深入的理解,并增强了我的编程技能。


7-2 队列应用(蓝桥杯)

1.实验设计思路:


初始化两个空队列vip_queuenormal_queue

遍历M次操作:

如果是IN name V类型的操作,将用户加入vip_queue

如果是OUT V类型的操作,将vip_queue队头的用户弹出并记录其姓名,同时将该用户加入normal_queue

如果是IN name N类型的操作,将用户加入normal_queue

如果是OUT N类型的操作,将normal_queue队头的用户弹出并记录其姓名。

遍历结束后,vip_queue中剩余的元素即为VIP窗口队列中的姓名,normal_queue中剩余的元素即为普通窗口队列中的姓名。

2.实验后的感想:


通过实现队列的操作,我不仅增强了自己的编程技能,还加深了对数据结构原理的理解。在解决这个问题时,我使用了队列来存储每个窗口的用户,并使用 IN OUT 操作来模拟用户的进入和离开。此外,这个实验还让我意识到计算机科学在实际生活中的应用。在现实生活中,我们经常会遇到排队的情况,如银行、超市等。通过这个实验,我理解到计算机科学中的数据结构可以用来解决这些问题,使排队更加高效、有序。