利用双栈计算表达式

思路如下:
用栈计算表达式的方法原理及步骤: 
建立两个栈,一个是数据栈,一个是计算符号栈,以(6+2*5)/4为例 
1 优先级 
符号之间的优先级如下: 
"(" , ")"        -1 
"+" , "-"       0 
"*" , "/"        1 
数值越大,则越优先,同级别的比较时 先出现的优先。 
2 将"(",")"设为特殊运算符,即单目运算,两邻两个运算符则可对消。 
3 计算条件 
(1) 当前运算符不等于""(特殊结束符) 
(2) 运算符栈里的运行算个数>=1时 
(3) 出栈口的运算符优先级高于将要入栈的运算符时或者两者可对消时。 
4 计算时,则将符号出栈参与计算,数值栈的出栈口前两位元素出栈参与计算,
计算结果值向数值栈压栈,并进行递归此操作。具体步骤如下: 
(1) "(" 压入符号栈 
(2) "6"压入数值栈 
(3) "("与"+"比较优先级,认为"("比"+"优先级低,则不满足计算条件,将"+"压入符号栈. 
(4) 将"2" 压入数值栈。 
(5) 将"*"与"+"比较优先级,算得"+"优先级低于"*",则不满足计算条件,将"*"压入符号栈。 
(6) 将 "5"压入数植栈。 
(7) 将"*"与")"比较优先级,得出"*"比")"优先级要高。进行计算,将"*"出栈、"5"、"2"出栈,参与计算 
(8) 将 2*5 =10的结果压入数值栈。 
(9) (递归)比较 "+"与")"优先级,得出"+"比")"优先级要高。再进行计算,将"+"出栈、"10"、"6"出栈,参与计算。 
(10) 将 6+10 =16的结果压入数值栈。 
(11) (递归)比较 ")"与"("优先级,得出两者可以对消,将"("符号出栈,与")"对消,继续取下一个符号。 
(12) 将"/"入符号栈。 
(13) 将"4"入数值栈。 
(14) 发现""算式结束符,则进行计算, 将 "/"、"4’、"16"出栈,参与计算。 
(15) 将计算结果压入数值栈。
struct Operator
{
OperatorType OpType;
int Value;    //如果是操作数则为数值,若是运算符则为优先级表中下标
};
stack<Operator>        OPND;                        //运算数栈
stack<Operator>        OPTR;                            //运算符栈
vector<Operator>    g_vecExpression;        //表达式向量
char OpPriority[7][7] = {{’>’,'>’,'<’,'<’,'<’,'>’,'>’},{’>’,'>’,'<’,'<’,'<’,'>’,'>’},
{’>’,'>’,'>’,'>’,'<’,'>’,'>’},{’>’,'>’,'>’,'>’,'<’,'>’,'>’},{’<’,'<’,'<’,'<’,'<’,'=’,’ ‘},
{’>’,'>’,'>’,'>’,’ ‘,’>’,'>’},{’<’,'<’,'<’,'<’,'<’,’ ‘,’='}};
// 比较算术符优先级
char Precede(Operator a,Operator b)  //比较两个运算符的优先级
{
return OpPriority[a.Value][b.Value];
}
// 计算子表达式
Operator Operate(Operator a,Operator theta,Operator b)
{
Operator result;
result.OpType = TokenValue;
switch(theta.OpType)
{
case TokenPlus:
result.Value = a.Value + b.Value;
break;
case TokenMinus:
result.Value = a.Value – b.Value;
break;
case TokenMultiply:
result.Value = a.Value * b.Value;
break;
case TokenDivide:
result.Value = a.Value / b.Value;
break;
}
return result;
}
int EvaluateExpression()
{
//’#'入运算符栈
Operator OpStart;
OpStart.OpType = delimiter;
OpStart.Value = 6;
OPTR.push(OpStart);
index =0;
//’#'界限符不相遇则继续循环
while( g_vecExpression[index].OpType != delimiter || OPTR.top().OpType != delimiter )
{
if( !isOperator(g_vecExpression[index]) )
{
//如果不是运算符,入运算数栈
OPND.push(g_vecExpression[index]);
index++;
}
else
{
switch( Precede(OPTR.top(),g_vecExpression[index]) )    //比较优先级
{
case ‘<’:
//优先级大于栈顶,运算符入栈
OPTR.push(g_vecExpression[index]);
index++;
break;
case ‘=’:
OPTR.pop();
index++;
break;
case ‘>’:
//小于则出栈进行计算
Operator theta = OPTR.top();
OPTR.pop();
Operator b = OPND.top();
OPND.pop();
Operator a = OPND.top();
OPND.pop();
OPND.push(Operate(a,theta,b));
break;
}
}
}
return OPND.top().Value;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值