表达式中所涉及的运算符有:单目运算符+-,双目运算符+, -, *, /, %,^(a^b=pow(a,b))
表达式中,负数必须写成形式为:(-num),其中num>0,表达式必须以等号结束
基本思想:
利用两个栈,一个为运算符栈operatorstack,一个为运算数栈operandstack,得到输入表达式后,从左到右扫描式子,若为运算数,压入operandstack,运算符则先与栈operatorstack栈顶元素进行优先级比较,若小于栈顶元素,则弹出该栈顶元素,并从栈operandstack中弹出两个操作数进行计算,结果压入operandstack。
为了处理形式为(-num),设置两个标志int preisopr(前一元素为操作符)int preisopd(前一元素为操作数),如果 preisopr==2则将num 取反压入operandstack
代码如下:(其中lstack.h为链栈,代码在本blog中的栈与链栈中,地址:http://blog.csdn.net/iamsnowolf/archive/2007/03/02/1519714.aspx)
//3.2.07
//expression.cpp
//------------------------------------------------
#include<iostream.h>
#include<stdlib.h>
#include<math.h>
#include<ctype.h> //用于函数isdigit
#include"lstack.h"
//---------------------------------------------------
// 运算符 读入优先级 栈优先级 等级
// (单目)+- 0
// +- 1 1 -1
// */% 2 2 -1
// ^ 3 3 -1
// ( 4 -1 0
// ) 0 0 0
//
//
//--------------------------------------------------
class MathOperator
{
private:
//运算符及其优先级
char opr;
int inputprecedence;
int stackprecedence;
public:
MathOperator(void){};
MathOperator(char ch);
int operator>=(MathOperator a) const;
void Evaluate(lstack<float> &operandstack);
char GetOpr(void) const;
};
MathOperator::MathOperator(char ch)
{
opr=ch;
switch(ch)
{
case '^': inputprecedence=3;
stackprecedence=3;
break;
case '+':
case '-': inputprecedence=1;
stackprecedence=1;
break;
case '*':
case '/':
case '%': inputprecedence=2;
stackprecedence=2;
break;
case '(': inputprecedence=3;
stackprecedence=-1;
break;
case ')': inputprecedence=0;
stackprecedence=0;
break;
}
}
int MathOperator::operator >=(MathOperator a) const
{
return stackprecedence>=a.inputprecedence;
}
void MathOperator::Evaluate(lstack<float> &operandstack)
{
float operand1=operandstack.Pop();
float operand2=operandstack.Pop();
switch(opr)
{
case '+': operandstack.Push(operand2+operand1);
break;
case '-': operandstack.Push(operand2-operand1);
break;
case '*': operandstack.Push(operand2*operand1);
break;
case '/': operandstack.Push(operand2/operand1);
break;
case '%': operandstack.Push((int)operand2%(int)operand1);
break;
case '^': operandstack.Push(pow(operand2,operand1));
break;
}
}
char MathOperator::GetOpr(void) const
{
return opr;
}
//检查读入字符是否为运算符或左括号,是返回1,不是返回0
const int MAXOPTR=7;
char optr[MAXOPTR]={'+','-','*','/','(','%','^'};
int isoperator(char ch)
{
int i=0,flag=1;
char c;
while(flag&&i<MAXOPTR)
{
if(ch==(c=optr[i]))
flag=0;
else i++;
}
return !flag;
}
int iswhitespace(char ch)
{
if(ch==' '||ch=='/n'||ch=='/t')
return 1;
else return 0;
}
//出错处理
enum ErrorType{Operator,Operand,Left,Right,Invalid};
void Error(int n)
{
static char *errormsgs[]={
"Operator expected",
"Operand expected",
"Missing left parenthesis",
"Missing right parentheses",
"Invalid input"
};
cerr<<errormsgs[n]<<endl;
exit(1);
};
//表达式求值
float evaluate(void)
{
lstack<float> operandstack;
lstack<MathOperator> operatorstack;
MathOperator opr1,opr2;
int rank=0;
int preisopr=0; //前一数据是操作符
int preisopd=0; //前一数据是操作数
float number;
char ch;
//处理表达式直到读入=
while(cin.get(ch)&&ch!='=')
{
//-----处理浮点数
if(isdigit(ch)||ch=='.')
{
cin.putback(ch);
cin>>number;
rank++; //操作数级别为1
if(rank>1)
Error(Operator);
if(preisopr==2) //如果是负数
number=-number;
operandstack.Push(number);
preisopr=0;
preisopd=1;
}
//-----处理运算符
else if(isoperator(ch))
{
if(ch!='(')
{
if(preisopr==0&&preisopd==1) //如果是双目运算符
{
preisopr++;
preisopd=0;
rank--; //操作符级别为-1
}
else if(preisopr==0&&preisopd==0) //如果是单目运算符
{
if(ch!='-')Error(Invalid);
preisopr=2;
continue;
}
else if(preisopr==1) //如果是单目运算符
{
if(ch!='-')Error(Invalid);preisopr++;
continue;
}
else if(preisopr>=2) //非法
Error(Invalid);
}
if(rank<0)
Error(Operand);
//建立一个存放当前运算符的MathOperator对象,其栈顶运算符的优先级>=
//当前运算符优先级,则弹出栈顶运算符并执行其运算。将当前运算符压入栈中
opr1=MathOperator(ch);
while(!operatorstack.StackEmpty()&&(opr2=operatorstack.Peek())>=opr1)
{
opr2=operatorstack.Pop();
opr2.Evaluate(operandstack);
}
operatorstack.Push(opr1);
}
//-----处理右括号
else if(ch==')')
{
//建立一个存放)的MathOperator对象,弹出运算符栈并求值直到遇到(或栈为空
//若栈为空则遗失(,否则删除(
opr1=MathOperator(ch);
while(!operatorstack.StackEmpty()&&(opr2=operatorstack.Peek())>=opr1)
{
opr2=operatorstack.Pop();
opr2.Evaluate(operandstack);
}
if(operatorstack.StackEmpty())
Error(Left);
opr2=operatorstack.Pop(); //删除(
}
//---非法输入
else if(!iswhitespace(ch))
{ Error(Invalid);}
}
//完整表达式的级别应为1
if(rank!=1)
Error(Operand);
//用运算符栈完成表达式求值,若发现坐括号,则遗失右括号
while(!operatorstack.StackEmpty())
{
opr1=operatorstack.Pop();
if(opr1.GetOpr()==')')
Error(Left);
opr1.Evaluate(operandstack);
}
return operandstack.Pop();
}
int main(void)
{
float num;
num=evaluate();
cout<<num<<endl;
return(0);
}