表达式求值 (计算器)
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; const int MAX=1505; char data[MAX]; //存放输入的表达式 double num[MAX]; //存表达式中的数字 char sign[MAX]; //存表达式中的符号 int ntop,stop,w; //ntop标记数字栈顶元素的位置,stop标记符号栈顶元素的位置 double sum; //结果 int kk; //菜单类 class menu { public: void getmenu(); //菜单的构造函数 }; //菜单的构造函数的具体实现 void menu::getmenu() { cout<<"========================================================\n"; cout<<"=================这是一个计算器程序=====================\n"; cout<<"========================================================\n"; cout<<"* 说明:可以进行+ - * / 操作您还可以用括号输入您的表达式 *\n"; cout<<"* 您输入表达式不需要输=号 例:您可输入(1+2)*3//4+5 然后回车 *\n"; cout<<"========================================================\n\n"; cout << "\t\t输入exit回车,结束程序运行\n\n"; } //基本+-*/计算类 class dshn { char * sign; public: dshn() //类构造函数的具体实现 { sign=NULL; //把sign的指针初始化为空 } void count(char * signs); //实现基本+-*/运算的函数 }; //基本的+-*/运算函数的具体实现 void dshn::count(char * signs) { sign=signs; if(sign[stop]=='+') //判断符号栈栈顶符号 { num[ntop-1]+=num[ntop]; //取当前数字栈栈顶前两数字进行该符号运算,结果存入栈顶前一个单元 ntop--; //抛掉数字栈顶元素,以便下一个新数字存入栈顶 } else if(sign[stop]=='-') { num[ntop-1]-=num[ntop]; ntop--; } else if(sign[stop]=='*') { num[ntop-1]*=num[ntop]; ntop--; } else if(sign[stop]=='/') { if(num[ntop]==0) { kk=1; } else { num[ntop-1]/=num[ntop]; ntop--; } } else if(sign[stop]!='\0'&&sign[stop]!='('&&sign[stop]!=')') //存在错误符号 { kk=1; } stop--; //抛掉符号栈顶元素,以便下一个新符号存入栈顶 } int main() { int len,m; //记录表达式的长度 menu menus; // 创建一个menu类型的实例 menus.getmenu();//调用菜单构造函数显示菜单 while(~scanf("%s",data)) { w=1; //判断是否出现‘-’代表负号的运算符 kk=0; //判断是否存在错误符号的标记初始化 m=0; //记录同时出现连续符号的个数 if(!(strcmp(data,"exit"))) //退出 break; dshn ob; //创建一个menu类型的实例 ntop=0; //记录数字栈栈顶元素的位置 stop=0; //记录符号栈栈顶元素的位置 int markn=0,marks=0,marknode=0; double ans=0,nodes; len=strlen(data); //计算表达式的长度 for(int i=0; i<=len; i++) { if(i!=len&&(data[i]>='0'&&data[i]<='9'||data[i]=='.')) //找出表达式字符串中的数字并转化成数字 { if(data[i]=='.')//小数 { marknode=1;//标记 nodes=0.1; } else { if(marknode) //小数 { ans=ans+(data[i]-'0')*nodes; //转化成数字 nodes=nodes*0.1; } else //整数 ans=ans*10+data[i]-'0'; markn=1; //标记得到一个数字 } } else { if(markn) //得到一个新数字 { num[++ntop]=ans; //将新数字存到数字栈栈顶 markn=0; marknode=0; ans=0; } else //若没有数字,则第一个为符号或者出现连续符号 { if(data[i]!='('&&data[i]!=')'&&data[i]!='\0') { m++; //连续出现符号则m++记录下来 if(m==2) //若出现连续的三个符号或开始就出现两个符号,则程序必定出错,跳出循环 { kk=1; break; } if(data[i]=='-') //如果出现负符号,则w记录为-1 { w=-1; continue; } else if(data[i]=='+') //如果出现正符号,则w不需要变化,无影响 continue; } } if(i==len) { if(w==-1) num[ntop]=-num[ntop]; break; } //表达式已计算完跳出for循环 if(w==-1) num[ntop]=-num[ntop]; if(data[i]=='-'||data[i]=='+') //表达式当前元素为'+'或'-' { while(stop&&sign[stop]!='(') //计算当前可计算的部分 { ob.count(sign); } sign[++stop]=data[i]; //将新符号压入栈顶 } else if(data[i]=='*'||data[i]=='/') { while(stop&&(sign[stop]=='*'||sign[stop]=='/')) //计算当前可计算的部分 { ob.count(sign); } sign[++stop]=data[i]; //将新符号压入栈顶 } else if(data[i]==')') { while(stop&&sign[stop]!='(') { ob.count(sign); } stop--; //括号内的值已存到数字栈,删掉'(' } else sign[++stop]=data[i]; w=1; //运算结束后重新标记为1 m=0; //出现数字后重新清0 } } if(kk==1) { cout<<"error"<<endl; continue; } while(stop) { ob.count(sign); } ob.count(sign); if(kk==1) cout<<"error"<<endl; else printf("%.4lf\n",num[1]); } }