📄 evaluateexpression.cpp
字号:
#include<iostream.h>
#include<iomanip.h>
double *OpndBase,*OpndTop; //定义元素类型
char *OptrBase,*OptrTop; //定义元素类型
void InitStack() //初始化栈
{ OpndBase=new double[100];
OptrBase=new char[100];
OpndTop=OpndBase;
OptrTop=OptrBase;}
void DestoryStack() //销毁栈,并释放所占空间
{ delete[]OpndBase;
delete[]OptrBase;}
double GetTop(double *Top) //返回栈顶元素
{ return *(Top-1);}
char GetTop(char *Top) //返回栈顶元素
{ return *(Top-1);}
void Push(double *&Top,double m) //在栈顶插入新的栈顶元素
{ *Top=m;
Top++;}
void Push(char *&Top,char m) //在栈顶插入新的栈顶元素
{ *Top=m;
Top++;}
void Pop(double *&Top,double &m) //删除栈顶元素,并以m返回其值
{ m=*(Top-1);
Top--;}
void Pop(char *&Top,char &m) //删除栈顶元素,并以m返回其值
{ m=*(Top-1);
Top--;}
int isp(char m) //返回运算符m在栈内所对应的优先权
{ switch (m){
case '#': return 0;
case '(': return 1;
case '+': return 3;
case '-': return 3;
case '*': return 5;
case '/': return 5;
case ')': return 6;
default: return 0; }}
int icp(char m) //返回运算符m在栈外所对应的优先权
{ switch(m){
case '#': return 0;
case ')': return 1;
case '+': return 2;
case '-': return 2;
case '*': return 4;
case '/': return 4;
case '(': return 6;
default: return 0;}}
char Precede(char a,char b) //返回a,b优先权比较后的结果
{ if(isp(a)>icp(b))return '>';
if(isp(a)==icp(b))return '=';
if(isp(a)<icp(b))return '<';
return 0;}
double Operate(double p,char x,double q) //返回运算pxq后的结果
{ switch(x){
case '+': return p+q;
case '-': return p-q;
case '*': return p*q;
case '/': return p/q;
default: return 0; }}
void CoutOpnd(double *OpndTop,double *OpndBase,double y) //输出运算数栈
{ cout<<"OpndTop is: ";
while(OpndTop!=OpndBase)
{Pop(OpndTop,y);
cout<<setprecision(20)<<y<<" ";}
cout<<endl;}
void CoutOptr(char *OptrTop,char x) //输出运算符栈
{ cout<<"OptrTop is: ";
while(GetTop(OptrTop)!='#')
{Pop(OptrTop,x);
cout<<x<<" ";}
cout<<endl;}
int Expression(char *a) //若算术表达式a正确,则返回1,否则返回0
{ int k=1,m=0,n=0;
while(a[k]!='#')
{if(a[k-1]=='#')m++;
while(a[k]=='+'||a[k]=='-'||a[k]=='*'||a[k]=='/'||a[k]=='.'){m++;k++;}
if(a[k-1]=='+'||a[k-1]=='-'||a[k-1]=='*'||a[k-1]=='/')
{if(a[k]=='#'||a[k]==')')
//若表达式中加,减,乘,除后紧接着右括号或出现在表达式最后一个位置则输出错误并返回0
{cout<<"error: EvaluateExpression isn't right."<<endl;return 0;}}
if(a[k-1]=='.')
//若表达式中小数点后紧接着括号或出现在表达式最后一个位置则输出错误并返回0
{if(a[k]=='#'||a[k]==')'||a[k]=='(')
{cout<<"error: EvaluateExpression isn't right."<<endl;return 0;}}
if(m>=2)
//若表达式中加,减,乘,除和小数点连续出现或出现在表达式第一个位则输出错误并返回0
{cout<<"error: EvaluateExpression isn't right."<<endl;return 0;}
m=0;
if('0'<=a[k]&&a[k]<='9')
{while('0'<=a[k]&&a[k]<='9')k++;
if(a[k]=='(')
//若表达式中数值后紧接着左括号则输出错误并返回0
{cout<<"error: EvaluateExpression isn't right."<<endl;return 0;}
k--;}
if(a[k]=='(')n++;
if(a[k]==')')n--;
k++;}
if(n>0||n<0)
//若表达式中括号没有配对出现则输出错误并返回0
{cout<<"error: EvaluateExpression isn't right."<<endl;return 0;}
return 1;} //表达式正确则返回1
double change(char c) //把字符型转换为双精度型
{ return double(c-'0');}
void func(char *a) //求值函数
{if(Expression(a)) //判断算术表达式是否正确
{InitStack(); //初始化栈
char x;
int i=1,v=0,j=0,zero=1;
double m=0,n=0,p,q,y; //定义元素类型
Push(OptrTop,'#'); //放置结束符
while(zero&&(a[i]!='#'||GetTop(OptrTop)!='#')){
//判断表达式是否结束或者遇到错误运算
while('0'<=a[i]&&a[i]<='9'){
n=change(a[i]);
m=m*10+n;v=1;i++;}
if(v)
{Push(OpndTop,m);v=0;m=0;}
if(a[i]=='.') //判断是否带小数
{++i;
while('0'<=a[i]&&a[i]<='9'){
n=change(a[i]);m=m*10+n;v=1;j++;i++;}
for(int e=0;e<j;e++)m=m/10;
Pop(OpndTop,y);y+=m;
Push(OpndTop,y);v=0;m=0;j=0;} //运算数进栈
CoutOpnd(OpndTop,OpndBase,y); //输出运算数栈
if(a[i]!='#'||GetTop(OptrTop)!='#') //判断表达式是否结束
switch(Precede(GetTop(OptrTop),a[i])){
case '<': //栈顶元素优先权低并运算符进栈,输出运算符栈
Push(OptrTop,a[i]);CoutOptr(OptrTop,x);i++;break;
case '=': //输出运算符栈,脱括号并接收下一个字符
CoutOptr(OptrTop,x);Pop(OptrTop,x);i++;break;
case '>': //输出运算符栈,退栈并将运算结果入栈
CoutOptr(OptrTop,x);
Pop(OptrTop,x);
Pop(OpndTop,q);
Pop(OpndTop,p);
if(x=='/'&&q==0)zero=0; //判断被除数是否为0
Push(OpndTop,Operate(p,x,q));break;}}
if(zero){ //若没有遇到除以0则输出结果,若遇到除以0则输出错误
cout<<"the result of operation is:"<<endl;
cout<<setprecision(20)<<GetTop(OpndTop)<<endl;}
else cout<<"error: cann't to divide zero."<<endl;
DestoryStack();}} //销毁栈,并释放所占空间
void main()
{ char a[100];
cout<<"please input a EvaluateExpression:"<<endl;
cin>>a; //输入算术表达式
func(a); } //调用函数
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -