——整理于20-7-7
后续持续改进
初版:
注:输入以#结束,仅支持+ - * /()
//表达式求值
#include<iostream>
#include<stack>
#include<cmath>
using namespace std;
#define MAX 100
typedef double NUMTYPE;
void mainprogram();//主程序
bool inputjudge(char *e);//输入合法性判断
NUMTYPE numchange(char *e, int &i);//遇到数字的转化
NUMTYPE EvaluateExpression(char *exp);//表达式求值程序
char precede(char ch1, char ch2);//判断先后顺序
NUMTYPE Operate(NUMTYPE a, char theta, NUMTYPE b);//计算程序
bool numjudge(char ch);//判断是否是数字
int main()
{
mainprogram();
return 0;
}
void mainprogram()//主程序
{
char exp[MAX];
cout<<"please input a expression(the end must be #):"<<endl;
cin>>exp;
while(!inputjudge(exp))
{
cout<<"Illega; input, please input again:"<<endl;
cin>>exp;
}
cout<<"result: "<<EvaluateExpression(exp)<<endl;
}
bool inputjudge(char *e)//输入合法性判断
{
char a[18]={'+', '-', '*', '/', '(', ')', '#', '.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
int k=0;
while(e[k]!='\0')
k++;
if(e[k-1]!='#')
return false;
for(int j=0; e[j]!='\0'; j++)
{
bool flag=false;
for(int i=0; i<18; i++)
{
if(e[j]==a[i])
{
flag=true;
break;
}
}
if(!flag)
return false;
}
return true;
}
NUMTYPE numchange(char *e, int &i)//遇到数字的转化
{
int integer=1, decimals=0, k=0, j=0;
int inte[MAX], deci[MAX];
NUMTYPE result=0;
inte[k++]=e[i-1]-'0';
bool flag=true;
while( (e[i]>='0'&&e[i]<='9') || e[i]=='.' )
{
if(e[i]=='.')
{
flag=false;
i++;
continue;
}
if(flag)
{
integer++;
inte[k++]=e[i]-'0';
}
else
{
decimals++;
deci[j++]=e[i]-'0';
}
i++;
}
for(int m=0; m<integer; m++)
{
result=result+inte[m]*pow(10, integer-m-1);
}
for(int m=0; m<decimals; m++)
{
result=result+deci[m]*pow(10, -(m+1));
}
return result;
}
NUMTYPE EvaluateExpression(char *exp)
{
char theta;
NUMTYPE a, b;
int i=0;
stack<char> OPE; //运算符栈
stack<NUMTYPE> NUM; //运算数栈
OPE.push('#');
char ch=exp[i++];
while(ch!='#'||OPE.top()!='#')
{
if(numjudge(ch))
{
NUM.push( numchange(exp, i) );
ch=exp[i++];
}
else
{
switch(precede(OPE.top(), ch))
{
case '<':
OPE.push(ch);
ch=exp[i++];
break;
case '=':
OPE.pop();
ch=exp[i++];
break;
case '>':
theta=OPE.top();
OPE.pop();
b=NUM.top();
NUM.pop();
a=NUM.top();
NUM.pop();
NUM.push(Operate(a, theta, b));
break;
case '0':
cout<<"表达式语法有误,程序终止"<<endl;
exit(-1);
}
}
}
return NUM.top();
}
char precede(char ch1, char ch2)//判断先后顺序
{
int nu1, nu2;
char a[8]={'0', '+', '-', '*', '/', '(', ')', '#'};
char array[8][8]={ {'0', '+', '-', '*', '/', '(', ')', '#'},
{'+', '>', '>', '<', '<', '<', '>', '>'},
{'-', '>', '>', '<', '<', '<', '>', '>'},
{'*', '>', '>', '>', '>', '<', '>', '>'},
{'/', '>', '>', '>', '>', '<', '>', '>'},
{'(', '<', '<', '<', '<', '<', '=', '0'},
{')', '>', '>', '>', '>', '0', '>', '>'},
{'#', '<', '<', '<', '<', '<', '0', '='} };
for(int i=0; i<8; i++)
{
if(a[i]==ch1)
nu1=i;
if(a[i]==ch2)
nu2=i;
};
return array[nu1][nu2];
}
NUMTYPE Operate(NUMTYPE a, char theta, NUMTYPE b)//计算程序
{
switch (theta)
{
case '+':
return a+b;
case '-':
return a-b;
case '*':
return a*b;
case '/':
return a/b;
};
}
bool numjudge(char ch)//判断是否是数字
{
if(ch>='0'&&ch<='9')
return true;
return false;
}