表达式分成
前缀,中缀,后缀表达式。
运算符的位置在哪就是前中后表达式。
考点
1,后缀表达式求值。
不需要考虑运算符的优先级,从左到右运算就行
中缀表达式:
(2+4)*3-9/3
后缀表达式:
2 4 + 3 * 9 3 / -
ans=15
Scanner s=new Scanner(System.in);
String tt=s.nextLine();
String t[]=tt.split(" ");
Stack<Double> st=new Stack();
for(int i=0;i<t.length;i++)
{
if(t[i].matches("\\d")) st.add(Double.valueOf(t[i]));
else {
double a=st.pop();double b=st.pop();
if(t[i].equals("+")) st.add(a+b);
if(t[i].equals("-")) st.add(b-a);
if(t[i].equals("*")) st.add(a*b);
if(t[i].equals("/")) st.add(b/a);//用之前的元素除以后面新来的元素
}
}
double ans=st.pop();
System.out.println(ans);
2,中缀表达式转后缀表达式
中缀表达式:a/b^c+de-ac
栈:保存运算符。
操作:
1,数字,直接放入后缀表达式中
2, 运算符,判断运算符优先级
如果优先级高于栈内运算符,则压入栈内
如果不高于栈内运算符,栈内符号高于或等于后要进的元素依次弹出放进表达式中,再压入栈内
3,括号匹配:
如果遇到(直接入运算符栈
如果遇到),把最靠近的(及后的运算符依次弹出。运算符放进表达式中,括号不需要。
4,如果遇到+,-的单目运算符(如-a),将0和数字放在表达式中 (为0a-);
3,中缀表达式转后缀表达式,后缀表达式求值 案例
#include<bits/stdc++.h>
#define fori(i,s,e) for(int i=s;i<=e;i++)
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> PII;
stack<char> s;//存放运算符的栈
queue<string> q;//输出队列(用于计算后缀表达式)
stack<double> sum;//用于计算后缀表达式(本文未实现计算后缀表达式)
string str = "";//读取整个数字串并保存
int isp(char c)//栈内元素优先级判断
{
switch (c)
{
case '#':
return 0;
case '(':
return 1;
case '+':
case '-':
return 3;
case '*':
case '/':
case '%':
return 5;
case ')':
return 6;
}
return 0;
}
int icp(char c)//栈外元素优先级判断
{
switch (c) {
case '#':
return 0;
case ')':
return 1;
case '+':
case '-':
return 2;
case '*':
case '/':
case '%':
return 4;
case '(':
return 6;
}
return 0;
}
void postfix(string input)//中缀表达式转后缀表达式代码
{
s.push('#');//将#压入栈顶
input += '#';//添加#号作为结束符
for (int i = 0; i < input.length(); i++)
{
if ((input[i] >= '0' && input[i] <= '9') || input[i] == '.')
{
str += input[i];
}
else
{
if (str.length() > 0)//将数放入直接输出到队列中
{
q.push(str);
str = "";
}
while (isp(s.top()) > icp(input[i]))
{
string a;//因为不能直接在栈和队列间转换字符和字符串类型,所以先将字符转成 字符串再出栈进队列
a = s.top();
q.push(a);
s.pop();
}
//判断站外元素优先级决定元素是应该去除(=),还是进栈(<)
if (isp(s.top()) == icp(input[i]))
{
s.pop();
}
else
{
s.push(input[i]);
}
}
}
}
int main()
{
string input;
string och;
cin >> input;
postfix(input);
// while (q.empty() == false)//队列不为空则输出队列元素
// {
// och=q.front();
// cout << och<<" " ;
// q.pop();
// }
stack<int> ans;
while(q.size()) {
string i = q.front();q.pop();
if(i[0]>='0'&&i[0]<='9') {
int dig = atoi(i.c_str());
ans.push(dig);
}else {
int t = ans.top();ans.pop();
int t2 = ans.top();ans.pop();
if(i[0] == '+') ans.push(t2+t);
if(i[0] == '-') ans.push(t2-t);
if(i[0] == '*') ans.push(t2*t);
if(i[0] == '/') ans.push(t2/t);
}
}
cout<<ans.top()<<endl;
return 0;
}
4,计算中缀表达式
#include<bits/stdc++.h>
#define fori(i,s,e) for(int i=s;i<=e;i++)
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> PII;
const int N = 100005;
int n,m;
int compute(string& s, int left, int right){
char op = '+'; //默认加开始
int num = 0;
vector<int> st;
for(int i = left; i <= right; i++){
if(isdigit(s[i])) //数字
num = num * 10 + s[i] - '0'; //计算该部分数字总和
if(s[i] == '{' || s[i] == '[' || s[i] == '('){ //进入左括号
int layer = 0; //统计左括号层数
int j = i;
while(j <= right){ //遍历到右边
if(s[j] == '{' || s[j] == '[' || s[j] == '(')
layer++; //遇到左括号,层数累加
else if(s[j] == '}' || s[j] == ']' || s[j] == ')'){
layer--; //遇到右括号层数递减
if(layer == 0) //直到层数为0
break;
}
j++;
}
num = compute(s, i + 1, j - 1); //递归计算括号中的部分
i = j + 1;
}
if(!isdigit(s[i]) || i == right){ //遇到运算符或者结尾
switch(op){ //根据运算符开始计算
case '+': st.push_back(num); break; //加减法加入到末尾
case '-': st.push_back(-num); break;
case '*': st.back() *= num; break; //乘除法与末尾计算
case '/': st.back() /= num; break;
}
op = s[i]; //修改为下一次的运算符
num = 0;
}
}
int res = 0;
for(int x : st) //累加和
res += x;
return res;
}
int main(){
string s;
while(cin >> s){
cout << compute(s, 0, s.length() - 1) << endl;
}
return 0;
}