c++ 手写计算器
数据结构课上老师布置了个作业,让自己写一个计算器,要求支持小数运算及括号,早上刷牙时构思了一下,发现可以用两个栈来实现。
其中,一个栈用来存运算符,一个栈用来存运算的数,利用栈将输入的中缀表达式转化为计算机容易处理的后缀表达式,当存运算符的栈中pop出运算符时,就取存运算数的栈上的前两个进行运算,在将运算结果压入栈中。
具体实现代码如下
#include<iostream> #include<cstring> #include<stack> using namespace std; stack<double> num; //double型的栈,用来存运算中的数 stack<char> opert; //char型的栈,用来存运算符 void calc(char c){ //此函数用来计算后缀表达式,每当opert栈中弹出运算符时,就取此栈中前两个进行运算,再将结果压入栈中 double a,b; //用a,b暂存数 a=num.top(); num.pop(); b=num.top(); num.pop(); if(c=='+') num.push(a+b); else if(c=='-') num.push(b-a); else if(c=='*') num.push(a*b); if(c=='/') num.push(b/a); } double solve(string s){ char top; double ans=0; char c; double n=0; int len=s.length(); double m=1,d=0; for(int i=0;i<len;i++){ c=s[i]; if(c>=48&&c<=57){ //如果c为0~9,则将其存在n 中,并用m,d来标记位数将数组中的数转换为int型 if(d==0.0){ n=n*m+int(c-48); m=10; } else{ n=n+d*int(c-48); d*=0.1; } } else if(c=='.'){ //如果c为'.',则将其d置为0.1中,并用d来标记位数中小数位数 d=0.1; } else if(c=='+'||c=='-'){ //如果c为'+'或'-' if(s[i-1]!=')') num.push(n); n=0; m=1; d=0; if(!opert.empty()){ top=opert.top(); while((top=='*'||top=='/'||top=='-')&&!opert.empty()){ //先看栈中是否为'*','/'或'-',若是,则调用calc函数进行相应出栈运算 calc(top); opert.pop(); if(!opert.empty()) top=opert.top(); } } opert.push(c); } else if(c=='*'||c=='/'){ //如果c为'*'或'/' if(s[i-1]!=')') num.push(n); n=0; m=1; d=0; if(!opert.empty()){ top=opert.top(); while((top=='/'&&c=='/')&&!opert.empty()){ calc(top); opert.pop(); if(!opert.empty()) top=opert.top(); } } opert.push(c); } else if(c=='('){ //如果c为'(',则直接压入栈中 opert.push(c); } else if(c==')'){ //如果c为')',则依次出栈并运算,直到弹出'(' num.push(n); if(!opert.empty()) top=opert.top(); while(top!='('){ calc(top); opert.pop(); top=opert.top(); } opert.pop(); } else{ printf("Error! Illgal input!EXIT_"); return 0; } } if(s[len-1]!=')') //判断运算式是否结束 num.push(n); while(!opert.empty()){ top=opert.top(); calc(top); opert.pop(); }; ans=num.top(); return ans; } int main(){ cout<<"Please input what u want to calculate:"; string s; cin>>s; //s="102.52+(5.3-9)"; //s="222+3"; cout<<solve(s); return 0; }
基本可以实现简单的运算
经验证结果正确
更新1 修复了一个bug
更新2 又修复了一个bug
更新3 双修复了一个bug