算法:后缀表达式,中缀表达式转后缀表达式,后缀表达式求值。

表达式分成
前缀,中缀,后缀表达式。
运算符的位置在哪就是前中后表达式。

考点

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值