【数据结构课设】 浮点数计算器

一.简介

 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;
}

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值