一.简介
1.功能介绍:实数的计算,支持取对数、幂次、开方及加减乘除运算
2.模块设计:
1)菜单界面
2)计算器功能简介
3)计算器功能实现
3.计算器功能实现方法:
1)字符串读入用户的表达式
2)处理字符串,包括提取实数以及中缀转后缀(维护一个运算符优先级严格单调递增的栈即可)
3)后缀表达式的计算
二.代码
#include <iostream>
#include <stack>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cmath>
#include <iomanip>
using namespace std;
typedef struct{
int tag; //tag=1表示操作符(的优先级)0表示操作符
char op;
double num;
}node;
void Menu(); //菜单
int Keyin(); //用户键入
void introduce(); //功能介绍
double Calculate(string s); //计算
void fun(string s); //字符串处理,转化为后缀
double num_read(string s); //字符转化为数
node expression[10000]; //后缀表达式
int cnt=0;
int check=0;
int main()
{
while(1){
int t=Keyin();
if(t==1)
introduce();
else if(t==3) return 0;
else{
int n;
string s;
cout<<"请输入你希望计算的表达式:"<<endl<<endl;
scanf(" ");
getline(cin,s);
double ans=Calculate(s);
while(check==1){
cout<<endl<<endl<<"你的输入不合法,请重新输入:"<<endl<<endl;
scanf(" ");
getline(cin,s);
ans=Calculate(s);
}
cout<<endl<<"你希望答案在小数点后保留几位?"<<endl<<endl;
cin>>n;
cout<<endl<<endl;
while(n<0){
cout<<endl<<endl<<"你的输入不合法,请重新输入:"<<endl<<endl;
cin>>n;
cout<<endl<<endl;
}
cout<<endl;
cout<<"答案是:";
cout<<fixed<<setprecision(n)<<ans<<endl<<endl;
system("pause");
system("cls");
}
}
return 0;
}
void introduce(){
system("cls");
for(int i=0;i<15;i++) cout<<'*';
cout<<"简易计算器功能介绍";
for(int i=0;i<15;i++) cout<<'*';
cout<<endl<<endl;
cout<<"操作数集合: 一切实数"<<endl<<endl;
cout<<"操作数限制: 数内部不能有空格"<<endl<<endl;
cout<<"操作符集合:加(+)、减(-)、乘(*)、除(/)、幂次(^)、开方(sqrt)、取对数(ln)"<<endl<<endl;
cout<<"注:2^3表示2的3次,sqrt(6)表示根号6,ln(5)表示对5取对数"<<endl<<endl;
cout<<"注:会对用户输入的表达式作合法性检查"<<endl;
system("pause");
}
int Keyin(){
system("cls");
Menu();
int key;
cout<<"请输入对应的数字(1~3):"<<endl<<endl;
cin>>key;
while(key<=0||key>=4){
cout<<endl<<endl<<"你的输入不合法,请重新输入:"<<endl<<endl;
cin>>key;
}
system("pause");
system("cls");
return key;
}
void Menu(){
for(int i=1;i<=15;i++) cout<<"=";
cout<<"Menu";
for(int i=1;i<=15;i++) cout<<"=";
cout<<endl<<"1.计算器功能介绍"<<endl<<endl;
cout<<"2.在线计算"<<endl<<endl;
cout<<"3.退出"<<endl<<endl;
for(int i=1;i<=35;i++) cout<<"=";
cout<<endl<<endl;
}
double num_read(string s){
double ret=(double)(s[0]-'0');
double power=10.0;//权重
int flag=0;
for(int i=1;i<s.size();i++){
if(s[i]=='.') {power=1.0,flag=1;continue;}
if(flag){
power/=10;
ret+=power*(double)(s[i]-'0');
}
else {
ret*=power;
ret+=(double)(s[i]-'0');
}
}
return ret;
}
void fun(string s){
cnt=0;
stack<node>st;
double flg=1;
for(int i=0;i<s.size();i++){
if(s[i]=='-'&&(i==0||s[i-1]=='(')) {flg=-1;continue;}
if(s[i]>='0'&&s[i]<='9'){
string t="";
while((s[i]>='0'&&s[i]<='9')||s[i]=='.')
t+=s[i],i++;
i--;
expression[cnt].num=flg*num_read(t);
flg=1;
expression[cnt++].tag=0;
continue;
}
node temp;
if(s[i]=='('||s[i]=='('){
temp.op='(';
temp.tag=0; //优先级设为0;
st.push(temp);
continue;
}
if(s[i]==')'||s[i]=='('){
while(st.top().op!='('){
expression[cnt++]=st.top();
st.pop();
}
st.pop();
}
int flag=0;
if(s[i]=='l'||s[i]=='L'||s[i]=='s'||s[i]=='S'||s[i]=='^'){
temp.tag=3;
flag=1;
}
else if(s[i]=='*'||s[i]=='/'){
temp.tag=2;
flag=1;
}
else if(s[i]=='+'||s[i]=='-'){
temp.tag=1;
flag=1;
}
if(!flag) continue;
temp.op=s[i];
if(st.empty()||temp.tag>st.top().tag) st.push(temp);
else{
while(!st.empty()&&temp.tag<=st.top().tag){
expression[cnt++]=st.top();
st.pop();
}
st.push(temp);
}
}
while(!st.empty()){
expression[cnt++]=st.top();
st.pop();
}
}
double Calculate(string s){
check=0;
fun(s);
stack<double>num;
for(int i=0;i<cnt;i++){
if(expression[i].tag==0)
num.push(expression[i].num);
else if((expression[i].op>='A'&&expression[i].op<='Z')||(expression[i].op>='a'&&expression[i].op<='z')){
if(num.size()==0) {check=1;return 0;}
double a=num.top(); num.pop();
double ret;
if(expression[i].op=='L'||expression[i].op=='l')
ret=log(a);
else if(expression[i].op=='S'||expression[i].op=='s')
ret=sqrt(a);
else {check=1;return 0;}
num.push(ret);
}
else{
if(num.size()<2) {check=1;return 0;}
double a=num.top(); num.pop();
double b=num.top(); num.pop();
double ret;
if(expression[i].op=='+') ret=a+b;
else if(expression[i].op=='-') ret=b-a;
else if(expression[i].op=='*') ret=a*b;
else if(expression[i].op=='/') ret=b*1.0/a;
else if(expression[i].op=='^') ret=(double)pow(b,a);
else {check=1;return 0;}
num.push(ret);
}
}
if(num.size()!=1) {check=1;return 0;}
double ans=num.top();
num.pop();
return ans;
}