中缀表达式求值模板

#include <bits/stdc++.h>
using namespace std;

/*判断符号间的优先关系函数
*1表示>,0表示=,-1表示<
*c1栈内的算符,c2栈外的算符
*/
int Judge(char c1,char c2)
{
int a1,a2;
if('+'==c1||'-'==c1) a1 = 3;
if('*'==c1||'/'==c1)a1 = 5;
if('('==c1) a1 = 1;
if(')'==c1) a1 = 7;
if('#'==c1) a1 = 0;

if('+'==c2||'-'==c2)a2 = 2;
if('*'==c2||'/'==c2)a2 = 4;
if('('==c2) a2 = 6;
if(')'==c2) a2 = 1;
if('#'==c2) a2 = 0;
if(a1>a2) return 1;
if(a1==a2) return 0;
if(a1<a2) return -1;
}
//符号运算函数
double run(char c ,double d1,double d2)
{
switch (c)
{
case '+':
return d1+d2;
break;
case '-':
return d1-d2;
break;
case'*' :
return d1*d2;
break;
case '/':
return d1/d2;
break;
default:
return 0.0;
break;
}
}
int main()
{
char * op = "+-*/()#";
string str ;
cin>>str;
//给表达式字符串str添加'#'结束标识符
str.append(1,'#');
stack<char> OPTR;//运算符栈
stack<double> OPND;//操作数栈
int a = -1;
//先将#符号入栈
OPTR.push('#');
while(true)
{
int b = a+1;
a = str.find_first_of(op,a+1);
if(a==string::npos) break;
if(a!=b)
{
string ss(str,b,a-b);
double d=atof(ss.c_str());
//数据先入栈
OPND.push(d);
}
//运算符优先级比较
int ju = Judge(OPTR.top(),str[a]);
if(-1==ju)//栈外优先级大直接入栈
{
OPTR.push(str[a]);
}
if(0==ju)//栈内外优先级相等则出栈
{
OPTR.pop();
}
if(1==ju)//栈内优先级大,出栈进行运算
{
double d1 = OPND.top();
OPND.pop();
double d2 = OPND.top();
OPND.pop();
d1 = run(OPTR.top(),d2,d1);
//运算结果入栈
OPND.push(d1);
OPTR.pop();
a--;
}
}
//删除表达式最后的'#'结束标识符
str.erase(str.length()-1,1);
cout<<str<<" = "<<OPND.top()<<endl;
}

转载于:https://www.cnblogs.com/gzhynl/p/9610249.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
中缀表达式求值是指将一个中缀表达式转换为后缀表达式,并计算后缀表达式的值的过程。具体步骤如下: 1. 创建一个操作数栈和一个运算符栈。 2. 从左到右扫描中缀表达式的每个元素。 3. 如果当前元素是操作数,则将其压入操作数栈中。 4. 如果当前元素是运算符,则进行如下操作: 1. 如果运算符栈为空,或者栈顶运算符为左括号,则将当前运算符压入运算符栈中。 2. 如果当前运算符的优先级大于栈顶运算符的优先级,则将当前运算符压入运算符栈中。 3. 否则,将运算符栈顶的运算符弹出并压入操作数栈中,直到当前运算符的优先级大于栈顶运算符的优先级。 5. 如果当前元素是左括号,则将其压入运算符栈中。 6. 如果当前元素是右括号,则进行如下操作: 1. 将运算符栈顶的运算符弹出并压入操作数栈中,直到遇到左括号。 2. 将左括号弹出,但不压入操作数栈中。 7. 如果中缀表达式的所有元素都已经扫描完毕,则将运算符栈中的所有运算符依次弹出并压入操作数栈中。 8. 最后,操作数栈中的唯一元素就是中缀表达式的值。 下面是一个示例中缀表达式求值的代码实现,使用C++模板类实现操作数栈和运算符栈: ```c++ #include <iostream> #include <stack> #include <string> using namespace std; template<typename T> class Stack { public: Stack(int n) { elem = new T[n]; top = -1; max_size = n; } ~Stack() { delete[] elem; } bool push(T x) { if (top == max_size - 1) { return false; } elem[++top] = x; return true; } bool pop(T& x) { if (top == -1) { return false; } x = elem[top--]; return true; } bool top(T& x) { if (top == -1) { return false; } x = elem[top]; return true; } bool empty() { return top == -1; } private: T* elem; int top; int max_size; }; int priority(char op) { switch (op) { case '+': case '-': return 1; case '*': case '/': return 2; default: return 0; } } int evaluate(string expr) { Stack<int> opnd(expr.length()); Stack<char> optr(expr.length()); int i = 0; while (i < expr.length()) { if (isdigit(expr[i])) { int num = 0; while (i < expr.length() && isdigit(expr[i])) { num = num * 10 + (expr[i] - '0'); i++; } opnd.push(num); } else if (expr[i] == '(') { optr.push(expr[i]); i++; } else if (expr[i] == ')') { char op; optr.pop(op); while (op != '(') { int b, a; opnd.pop(b); opnd.pop(a); switch (op) { case '+': opnd.push(a + b); break; case '-': opnd.push(a - b); break; case '*': opnd.push(a * b); break; case '/': opnd.push(a / b); break; } optr.pop(op); } i++; } else if (expr[i] == '+' || expr[i] == '-' || expr[i] == '*' || expr[i] == '/') { char op = expr[i]; while (!optr.empty() && optr.top() != '(' && priority(op) <= priority(optr.top())) { int b, a; opnd.pop(b); opnd.pop(a); char op2; optr.pop(op2); switch (op2) { case '+': opnd.push(a + b); break; case '-': opnd.push(a - b); break; case '*': opnd.push(a * b); break; case '/': opnd.push(a / b); break; } } optr.push(op); i++; } else { i++; } } while (!optr.empty()) { int b, a; opnd.pop(b); opnd.pop(a); char op; optr.pop(op); switch (op) { case '+': opnd.push(a + b); break; case '-': opnd.push(a - b); break; case '*': opnd.push(a * b); break; case '/': opnd.push(a / b); break; } } int result; opnd.pop(result); return result; } int main() { string expr = "3+4*5-(6+7)*8/9"; int result = evaluate(expr); cout << result << endl; return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值