首页 > 其他分享 >中缀表达式求值

中缀表达式求值

时间:2022-11-24 23:34:51浏览次数:65  
标签:字符 中缀 后缀 运算符 node1 求值 表达式

中缀表达式指的是形如(15+(32-1)×5+14÷2)的表达式,这种就是我们通常见到的书写算式顺序,但在实际的计算机运算中要计算中缀表达式则首先要将字符串转换为后缀表达式,

然后再根据后缀表达式的规则进行运算

输入一个字符串:

"(15+(32-1)×5+14÷2)"

输出:

177

要求:

1.不合法字符检查;

2.括号匹配错误检查;

3.运算错误检查,如除0操作;

/*
* 本题本质上是中缀表达式求值,需要先将中缀表达式转为后缀表达式,规则如下:
* 1)若当前的字符是数字,则连同其后面连续的数字作为一个整体操作数,以字符串的形式存入到后缀表达式数组;

* 2)若当前字符是左括号‘(’,则直接将其压入运算符栈中;

* 3)若当前字符是右括号‘)’,则将运算符栈中的运算符依放到后缀表达式数组中,每个运算符作为一项,直到遇到一个左括号‘(’,将该左括号出栈但不加入后缀表达式;

* 4)若当前字符是运算符,则将从栈顶开始优先级比当前运算符高或同优先级的依次出栈并加入后缀表达式中,直至 栈为空 | 栈顶字符为‘(’ | 栈顶运算符优先级比当前运算符低,然后将当前运算符压栈;

* 5)遍历完中缀表达式之后,将栈中剩下的运算符依次加入后缀表达式末尾。
* 后缀表达式计算方法如下:
* 6) 从左到右扫描后缀表达式,遇到integer压栈,遇到操作符从栈顶依次弹出两个数字参与运算。
* 7) 最后栈顶元素就是解
*/
#include <bits/stdc++.h>
using namespace std;
stack<char> s1;//字符栈
map<char,int> m;//建立hash来方便优先级比较
struct node//由于一个栈不能同时存放char和integer,所以建立结构体方便操作
{
    int x = 0;//存放数字
    char c;//存放字符
    node(int x,char c)//构造函数
    {
        this->x = x;
        this->c = c;
    }
};
vector<node> node1;//存放原始字符串
vector<node> a;//存放后缀后缀表达式
stack<node> s;//计算后缀表达式用的栈
int main()
{
    m['+'] = 1;
    m['-'] = 1;
    m['*'] = 2;
    m['/'] = 2;
    //确立字符优先级
    std::ios::sync_with_stdio(false);//加速cin
    string str = "";//以字符串的形式存下中缀表达式
    cout<<"请输入中缀表达式,退出请输入end"<<endl;
    while(cin>>str){
    if(str=="end")
    break;
    string temp = "";//存下连续的数字
    node1.clear();
    a.clear();
    for(int i = 0;i<str.length();i++)
    {
        if(str[i]-'0'>=0&&str[i]-'0'<=9)
            temp+=str[i];
        else if(m[str[i]]!=0||str[i]=='('||str[i]==')')//如果是合法操作符
        {
            if(temp!="")//temp不为空,记录了一个完整数字
            {
                istringstream is(temp);//建立stringstream转string为int
                int k;
                is>>k;
                node1.push_back(node(k,' '));
                temp = "";
            }
            node1.push_back(node(-9999,str[i]));//不是的话就放入字符
        }
        else
        {
            cout<<"非法字符"<<endl;
            exit(0);
        }
    }
            if(temp!="")//i=str.length()时temp可能不为空,这里要特判
            {
                istringstream is(temp);
                int k;
                is>>k;
                node1.push_back(node(k,' '));
                temp = "";
            }
    for(int i =0;i<node1.size();i++)//中缀转后缀
    {
        if(node1[i].x!=-9999)//参考1)
        {
            a.push_back(node1[i]);
        }
        else if(node1[i].c=='(')//参考2)
            s1.push('(');
        else if(node1[i].c==')')//参考3)
        {
        while(s1.top()!='(')
        {
            a.push_back(node(-9999,s1.top()));
            s1.pop();
            if(s1.empty())
            {
                cout<<"括号匹配错误"<<endl;
                exit(0);
            }
        }
        s1.pop();
        }
        else{
            while(!s1.empty()&&(m[s1.top()]>=m[node1[i].c]))//参考4)
            {
                a.push_back(node(-9999,s1.top()));
                s1.pop();
            }
            s1.push(node1[i].c);
        }
    }
    //cout<<s1.size()<<endl;
    while(s1.size()!=0)//参考5)
    {
        if(s1.top()!='('){
        a.push_back(node(-9999,s1.top()));
        s1.pop();
        }
        else
        {
            cout<<"括号匹配错误"<<endl;
            exit(0);
        }
    }
    for(int i =0;i<a.size();i++)//计算后缀表达式,参考6)
    {
        if(a[i].x!=-9999)
        {
            s.push(a[i]);
        }
        else{
            int x = s.top().x;
            s.pop();
            int y = s.top().x;
            s.pop();
            if(a[i].c=='+')
            {
                s.push(node(x+y,' '));
            }
            else if(a[i].c=='-')
            {
                s.push(node(y-x,' '));
            }
            else if(a[i].c=='*')
            {
                s.push(node(x*y,' '));
            }
            else{
                    if(x!=0)
                s.push(node(y/x,' '));
            else{
                cout<<"除0错误"<<endl;
                exit(0);
            }
            }
        }
    }
    cout<<s.top().x<<endl;//参考7)
    cout<<"请输入中缀表达式"<<endl;
    }
    return 0;
}

 

标签:字符,中缀,后缀,运算符,node1,求值,表达式
From: https://www.cnblogs.com/remarkableboy/p/16923849.html

相关文章

  • SpringBoot获取Cron表达式当天第一次执行时间
    //不废话,直接干CronSequenceGeneratorcronSequenceGenerator=newCronSequenceGenerator("0159,21**?");Datedate=DateUtils.toDate(LocalDate.now());Datey......
  • Java——多线程:Lamda表达式
    多线程理解继承Thread类子类继承Thread类具备多线程能力启动线程:子类对象.start()不建议使用:避免oop单继承局限性实现Runnable接口实现接口Runnable具有多......
  • EL表达式, JSTL, 获取map集合中key的value
    序言:今天在项目中使用了map存储list和普通对象,但是在jsp中显示的时候出来问题,后经查阅,终于解决,现在记录一下,以便以后查阅:一:后台代码如下:packagecn.gov.csrc.cms.action;imp......
  • EL表达式和JSTL标签快速入门
    <%Stringdata="mydata";request.setAttribute("data",data);%>${data}<%--pageContext.findAttribute("data")pagerequestsessionapplica......
  • jsonpath 表达式
    在进行对接数据时,经常会遇到对接的是接口数据。关于在对接接口类型的数据,数据返回的为json数组形式的数据,需要讲数组先解析出来,主要是通过 jsonpath表达式。jsonpath......
  • C#中利用正则表达式获取字符串中双引号包含的内容
    代码:usingSystem.Text.RegularExpressions;namespaceGetData{internalclassProgram{privatestaticvoidMain(string[]args){......
  • Lambda表达式Stream流的用法示例
    1、使用简单示例:@OverridepublicList<CategoryEntity>listWithTree(){//1、查询所有的分类数据List<CategoryEntity>entities=categoryDao.selectList(null......
  • 10_正则表达式匹配
    10.正则表达式匹配一、题目内容给你一个字符串s和一个字符规律p,请你来实现一个支持'.'和'*'的正则表达式匹配。'.'匹配任意单个字符'*'匹配零个或多个前面的......
  • 010.路径表达式用法
    1.加载单个配置文件  2.加载多个配置文件  3.路径表达式的书写方法 ......
  • 怎么定义正则表达式
    怎么定义正则表达式字面量定义,就是用两个"/"把表达式包裹起来。字面量定义的正则表达式可以赋值给变量,也可以在需要用到正则表达式的地方直接使用。//赋值给变量var......