C++计算器



用C++实现一个计算器,要求使用两个栈。其中一个用来保存操作数,一个用来保存操作符。该计算器可以实现基本的操作,比如+,-%,*,&(开方),^,(乘方)/



具体代码实现如下:(C++)



#include <iostream>
#include <stack>
#include <cmath>
#include <cstring>
using namespace std;

// = + - * / % ( ) ^ &
// 0 3 3 5 5 5 1 8 7 7-----in
// 0 2 2 4 4 4 8 1 6 6-----out


int inSta(char c); //记录栈内优先级
int outSta(char c); //记录栈外优先级

int checkCharType(const char c);
int charChangeInt(const char c);
double calCtemp(double num1,double num2,char c);

int main()
{
 //用户操作界面
 cout<<endl;
 cout<<endl;
 cout<<"              ************************温馨提示***********************"<<endl;
 cout<<"                                      操作说明:"<<endl;
 cout<<"            加(+) 减(-) 乘(*) 除(/) 取余(%) 括号()  开方(&) 乘方(^) " <<endl;
 cout<<"              ************************温馨提示***********************"<<endl;
 cout<<"                     请输入需要计算的公式<以“=”结束>"<<endl;
 cout<<endl;
 cout<<endl;
 
 while(1)
 {
 char judge;
 cout<<"please choose operate(Y/N):";
 cin>>judge;
 if(judge=='Y')
 {
 char strExp[1000];
 int expFormatFlag = 0;
 double expAns = 0.0;
 int ret=1;
 stack <char> optr; 
 stack <double> opnd; 
 optr.push('=');
 
 cout<<"Please enter the expression you want to calculate : "<<endl;

 scanf("%s",strExp);

 int ExpLen = strlen(strExp);

 for(int i = 0 ; i < ExpLen ; i++)
 {
  if(expFormatFlag)
  {
   break;
  }

  if(checkCharType(strExp[i]) == 5)
  {
   expFormatFlag = 1;
   break;
  }
  else if(checkCharType(strExp[i]) == 2 || checkCharType(strExp[i]) == 3)//optr
  {
      if(outSta(strExp[i]) < inSta(optr.top()))
            {
             while(outSta(strExp[i]) < inSta(optr.top()))
             {
                double x1 = opnd.top();
            
    opnd.pop();
                double x2 = opnd.top();
                opnd.pop();
                char c = optr.top();
                opnd.push(calCtemp(x2,x1,c));
    
    //cout<<"x2 "<<x2<<" x1 "<<x1<<" c "<<c<<endl;
    expAns = opnd.top();
    optr.pop();
   }
    if(strExp[i] == ')')
    {
     optr.pop();
     continue;
    }//if is 0
    
    
    if(strExp[i] == '=')
    { 
     //cout<<opnd.size()<<" --size()"<<endl;
     while(opnd.size() > 1)
     {
      double x1 = opnd.top();
      opnd.pop();
      double x2 = opnd.top();
      opnd.pop();
      char c = optr.top();
      opnd.push(calCtemp(x2,x1,c));
      expAns = opnd.top();
      optr.pop();
      //cout<<x1<<" "<<x2<<" "<<c<<endl;
      //cout<<calCtemp(x1,x2,c);
     }
     break;
    }
    optr.push(strExp[i]);
            }
            else if(outSta(strExp[i]) == inSta(optr.top()))
            {
                optr.pop();
            }
            else if(outSta(strExp[i]) > inSta(optr.top()))
            {
                optr.push(strExp[i]);
            }
  }//optr
  else if(checkCharType(strExp[i]) == 1)//opnd num
  {
   int tempDbPointNum = 0;
   int countLoc = 0;
   int tempDbNum = charChangeInt(strExp[i]);

   while(i<ExpLen)
   {
    if(strExp[i-1] == '-' && checkCharType(strExp[i-2]) != 1)
    {
     optr.pop();
     ret = -1;
    }
    i++;

    if(checkCharType(strExp[i]) == 1 )//num
    {
     tempDbNum *= 10;
     tempDbNum += charChangeInt(strExp[i]);
    }
    else if(checkCharType(strExp[i]) == 4)//point
    {
  
     while(i<ExpLen-1)
     {
      i++;
      if(checkCharType(strExp[i]) == 1)//num
      {
       tempDbPointNum *= 10;
       tempDbPointNum += charChangeInt(strExp[i]);
       countLoc++;
       //0.124 = ((1*0.1) + 2* 0.02) + 4 *0.03
      }
      else if(checkCharType(strExp[i]) == 4 || checkCharType(strExp[i]) == 5)//. or other
      {
       expFormatFlag = 1;
       break;
      }
      else
      {
       i--;
       break;
      }
     }

    }
    else//-------------------------------break;
    {
     if(expFormatFlag)
     {
      break;
     }
     else
     {
      double locN = 1;
      for(int k = 0; k < countLoc;k++)
       locN *= 10;
      double x1 = (double)tempDbPointNum/locN;
      double x2 = (double)tempDbNum;
      double tempNum = (x1+x2)*ret;
      //cout<<123456/100000000<<endl;

      opnd.push(tempNum);
      ret = 1;
      i--;
      break;
     }
    }

   } 
  }//opnd

  else if(checkCharType(strExp[i]) == 3)
  {
  
  }//ans

 }
 //ans is over
 if(expFormatFlag)
 {
  cout<<"Shabby Your input is illegal!"<<endl;
 }
 else
 {
  cout<<"Good job! The Ans is : "<<endl;
  cout<<expAns<<endl;
  cout<<"Thank you for your use , good bye ,nice gay"<<endl;
 }
}
   else
     break;
 }
}
int inSta(char c)      //记录栈外优先级
{
 switch(c)
 {
 case '=':
  return 0;
   break;

 case '+':
  return 3;
  break;

 case '-':
  return 3;
  break;

 case '*':
  return 5;
  break;

 case '/':
  return 5;
  break;

 case '%':
  return 5;
  break;

 case '(':
  return 1;
  break;

 case ')':
  return 8;
  break;

 case '^':
  return 7;
  break;

 case '&':
  return 7;
  break;

 default:
  break;
 }
}


int outSta(char c)       //记录栈外优先级
{
 switch(c)
 {
 case '=':
  return 0;
   break;

 case '+':
  return 2;
  break;

 case '-':
  return 2;
  break;

 case '*':
  return 4;
  break;

 case '/':
  return 4;
  break;

 case '%':
  return 4;
  break;

 case '(':
  return 8;
  break;

 case ')':
  return 1;
  break;

 case '^':
  return 6;
  break;

 case '&':
  return 6;
  break;

 default:
  break;
 }
}

int checkCharType(const char c)     //操作数,操作符判断
{
 if(c >= 0x30 && c <= 0x39)
  return 1;
 else if(c == '+' || c == '-' || c == '*' || c == '/' || c == '%' || c == '(' || c == ')' || c == '^' || c == '&')
  return 2;
 else if(c == '=')
  return 3;
 else if(c == '.')
  return 4;
 else
  return 5;
}

int charChangeInt(const char c)      //字符转化为数字
{
 return (int)(c-'0');
}

double calCtemp(double num1,double num2,char c)   //出栈运算
{
    switch(c)
    {
    case    '+':
        return  num1 + num2;
        break;
       
    case    '-':
        return  num1 - num2;
        break;
       
    case    '*':
        return  num1 * num2;
        break;
       
    case    '/':
        return  num1 / num2;
        break;
    case    '%':
        return  (double)((int)num1 % (int)num2);
        break;
       
    case    '&':
        return  pow(num1,(1/num2)); 
        break;
       
    case    '^':
        return  pow(num1,num2);
        break;
       
    default:
        break;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值