【题目链接】

ybt 1358:中缀表达式值(expr)

【题目考点】

1. 表达式求值

  • 中缀表达式转后缀表达式
  • 后缀表达式求值

【解题思路】

由于题目要求做中缀表达式转为后缀表达式,而后求值。那么这里就不给出其他求值方法了。

1. 先判断表达式是否合法

  1. 括号匹配:扫描整个算式,遇到左括号就入栈,遇到右括号,就出栈一次。在这一过程中,如果栈空了,还遇到右括号,那么表达式非法。
  2. 对于负号:行首的负号,以及'('后的负号,前面插入'0'
  3. 第一个字符不可以是运算符,除了'('。最后一个字符不可以是运算符,除了')'
  4. 检查是否有连续出现的运算符()±@
    如果连续两个字符是运算符:

    1. 如果两个字符是")(",那么是非法的。
    2. 除了上述情况,如果第一个是')',或第二个是'(',那么是合法的。
    3. 其余两个连续运算符出现的情况全是非法的

2. 中缀表达式转后缀表达式

  1. 设数组保存后缀表达式,设运算符栈。
    从左向右扫描表达式字符串:
  2. 遇到数字时,将数字添加到后缀表达式
  3. 遇到运算符时,入栈条件为:栈空,或该运算符优先级比栈顶运算符优先级高,或者栈顶是'('。只有不满足该条件,则一直出栈。出栈的运算符添加到后缀表达式。
  4. 扫描结束后若栈中有运算符,都出栈,加入后缀表达式。
    可以预先在字符串末尾加上一个优先级最低的')',以促使运算符栈中的运算符都出栈。

3. 求解后缀表达式

后缀表达式的求解方法见:信息学奥赛一本通 1331:【例1-2】后缀表达式的值

【题解代码】

解法1:中缀表达式转为后缀表达式,而后求值。

#include<bits/stdc++.h>
using namespace std;
#define N 1005
struct Node
{int n;char c;
};
Node eq[N];//保存后缀表达式
int p;
int pri[128];//pri[i]:ascii码为i的运算符的优先级
string s;//中缀表达式字符串
void initPri()
{pri['('] = 4;pri['*'] = pri['/'] = 3;pri['+'] = pri['-'] = 2;pri[')'] = 1;
}
int calc(int a, int b, char c)
{switch(c){case '+':return a+b;case '-':return a-b;case '*':return a*b;case '/':return a/b;}
}
bool isCalc(char c)//判断c是否是运算符
{return c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')';
}
bool isValid()//判断s是否是合法的中缀表达式
{//1.检查括号匹配 stack<char> stk;for(int i = 0; i < s.length(); ++i) {if(s[i] == '(')stk.push(s[i]);else if(s[i] == ')'){if(stk.empty())return false;elsestk.pop();}}if(stk.empty() == false)return false;//2.单独的负号前加0 for(int i = 0; i < s.length(); ++i){if(i == 0 && s[i] == '-')s = '0' + s;//前面加0else if(s[i] == '-' && s[i-1] == '(')//右括号后面的负号s.insert(i, "0");//在第i位置插入0 }//3. 除了首位的'('与末尾的')',其余情况首尾不能为运算符if(isCalc(s[0]) && s[0] != '(')return false;int ed = s.length()-1;//末尾位置下标 if(isCalc(s[ed]) && s[ed] != ')')return false;//4.判断是否有连续的不合法的运算符for(int i = 0; i < s.length()-1; ++i){if(isCalc(s[i]) && isCalc(s[i+1]))//如果有相邻两个运算符{if(s[i] == ')' && s[i+1] == '(')return false;else if(!(s[i] == ')' || s[i+1] == '('))//如果第一个是`')'`,或第二个是`'('`,那么是合法的。其余是非法的。 return false;}       } return true;
}
int solve()//递归求解后缀表达式
{int i = p--;if(eq[i].c){int b = solve(); int a = solve();return calc(a, b, eq[i].c);}elsereturn eq[i].n;
}
int main()
{initPri();//初始化pri数组 int n, num = 0;cin >> s;if(isValid() == false){cout << "NO";return 0;}s += ')';//取巧,把一个优先级最低的符号')'加到字符串末尾,促使运算符都出栈,以完成最后的计算。 stack<char> cStk;//运算符栈 bool isFormingNum = false;//标志位 表示是否正在构造数字 for(int i = 0; i < s.length(); ++i)//最后一次取到人为添加的')' {if(s[i] >= '0' && s[i] <= '9')//如果扫描到数字 {isFormingNum = true;num = num * 10 + s[i] - '0';//将字符串转化为数 }else//如果扫描到运算符 {if(isFormingNum)//如果正在构造数字 {eq[++p].n = num;//将构造好的数字加入后缀表达式 num = 0;//保存数字的变量复原isFormingNum = false;}while(!(cStk.empty() || pri[s[i]] > pri[cStk.top()] || cStk.top() == '('))//入栈条件:栈空或要入栈的运算符比栈顶的优先级更高或栈顶为左括号。入栈条件取反就是出栈条件。 {eq[++p].c = cStk.top(); cStk.pop();}if(cStk.empty() == false && cStk.top() == '(' && s[i] == ')')//如果左右括号配对 cStk.pop();//弹出左括号 不压栈 else cStk.push(s[i]);//运算符压栈 }}cout << solve();//求后缀表达式eq的值 return 0;
}

信息学奥赛一本通 1358:中缀表达式值(expr)相关推荐

  1. 信息学奥赛一本通1358 中缀表达式值(expr) ()

    1358:中缀表达式值(expr) 时间限制: 1000 ms         内存限制: 65536 KB 提交数: 4486     通过数: 1536 [题目描述] 输入一个中缀表达式(由0-9 ...

  2. 信息学奥赛一本通(基础算法与数据结构-题解汇总目录)

    信息学奥赛一本通(C++版)在线评测系统 基础(二)基础算法   更新中...... 第一章高精度计算 1307[例1.3]高精度乘法 1308[例1.5]高精除 1309[例1.6]回文数(Noip ...

  3. 信息学奥赛一本通——1012:计算多项式的值

    大家好 今天给大家带来<信息学奥赛一本通--1012:计算多项式的值> 看题目: 1012:计算多项式的值 时间限制: 1000 ms         内存限制: 65536 KB 提交数 ...

  4. 信息学奥赛一本通 1356:计算(calc)

    [题目链接] ybt 1356:计算(calc) [题目考点] 1. 表达式求值 中缀表达式求值 2. 表达式树 表达式树:一棵表达式树可以表示一系列的运算. 表达式树中的结点包括运算符与数值 str ...

  5. 信息学奥赛一本通 (C++)上机练习

    信息学奥赛一本通(C++)上机练习 此书为娃儿的第一本刷题书.娃儿现在四年级 ,希望他能坚持下来.特开贴加油 luogu: disangan223 第一部分 C++语言 第一章 C++语言入门 T10 ...

  6. 【信息学奥赛一本通】题解大全

    信息学奥赛一本通网站:点击这里 [语言及算法基础篇] 第一部分:C++语言 第一章:C++语言入门 T1000    入门测试题目      点击这里 T1001    Hello,World!    ...

  7. 信息学奥赛一本通(题解目录)

    信息学奥赛一本通(题解目录) 记录了我从初学者到逐渐熟悉c++的成长之路 信息学奥赛一本通OJ 目录 信息学奥赛一本通(题解目录) 前言 一.语言及算法基础篇 基础(一) C++语言 第一章 C++语 ...

  8. 信息学奥赛一本通在线提交地址

    信息学奥赛一本通 1 C++语言入门 1.1 综合 1.1.1 P1458 地球人口承载力估计 正确: 770 提交: 1794 比率: 42.92 % 1.1.2 P1686 Hello, Worl ...

  9. 信息学奥赛一本通1267:【例9.11】01背包问题(二维dp与滚动数组优化)

    [题目描述] 一个旅行者有一个最多能装 MM 公斤的背包,现在有 nn 件物品,它们的重量分别是W1,W2,...,WnW1,W2,...,Wn,它们的价值分别为C1,C2,...,CnC1,C2,. ...

最新文章

  1. 像素级动态模糊(Pixel Motion Blur)
  2. 【C 语言】指针数据类型 ( 指针类型变量 | 使用 * 操作内存 )
  3. 错误三次无法输入c语言,不懂就问,为啥错误输入三次不停止呢
  4. linux centos7内核降级和升级
  5. iOS之深入解析Runloop的底层原理
  6. atom feed_适用于Atom Feed的Spring MVC
  7. 成功男士的健康心理特征
  8. 【进阶】【转】项目经理常用工具
  9. 前方预警!Windows Server 将默认需符合 TPM2.0,服务器商需在来年 1 月 1 日前适配相应规则...
  10. C++程序调用python3
  11. ldap 测试表设计
  12. c++开源库rapidxml介绍与示例
  13. 全类销项发票电子化管理系统:iBox+RPA的开票流程数字化
  14. python新手怎么兼职-用Python在家兼职赚钱的4个方法
  15. android 编译太慢,如何解决android studio运行编译速度慢
  16. [NOI2015]小园丁与老司机
  17. 基于深度学习的移动网络异常检测
  18. qq邮箱日历同步服务器,QQ邮箱,腾讯企业邮箱,让你的日程跟着手机走
  19. 图文解说百兆和千兆网线制作方法
  20. D3D11和D3D12共享资源

热门文章

  1. 让TortoiseGit记住帐号密码方法
  2. 飘逸的python - 字典合并值相加
  3. 微软重拳出击:盗版 Windows 将无处遁形!
  4. 人间不值得?250000条数据分析李诞是不是被骂火的
  5. 【面试】彻底理解 IO多路复用
  6. ​Redis分布式锁,你真的用对了吗?
  7. 宁可相信世上有鬼,也不要相信产品经理那张破嘴?
  8. 【升级包】jeecg_online 支持主子表列表展示风格模板升级包,简易升级
  9. SpringBoot2 整合 Drools规则引擎,实现高效的业务规则
  10. SpringBoot2.0 整合 QuartJob ,实现定时器实时管理