自由练习-简单计算器

巧了我就是萌 提交于 2019-11-29 13:44:55

Q:读入一个只包含+-*/的非负整数计算表达式,计算该表达式的值。

样例输入:4+2*5-7/11

分析:利用堆栈对表达式求值是数据结构中典型的例子,算法分析如下:

1.设立两个堆栈,一个存储运算符,一个存储数字

2.表达式首尾添加标记运算符,且此运算符优先级最低。

3.从左到右遍历表达式,若为数字,则压入数据栈。

4.若为运算符,则与栈顶运算符进行优先级比较,如果当前运算符优先级高于(不低于)栈顶运算符,则当前运算符压入运算符栈;反之,则弹出栈顶运算符,同时连续弹出数字栈顶数字两次,计算后将结果压入数字栈,将当前运算符压入运算符栈。

5.重复3,4步,直到遇到标志运算符。

代码如下:

#include<stdio.h>
#include<stack>
#include<string>
#include<stdlib.h>
#define optsize 6

using namespace std;

char opt[optsize]={'+','-','*','/','#','='};//运算符集
int optcmp[optsize][optsize]=
{1,1,0,0,1,1,
 1,1,0,0,1,1,
 1,1,1,1,1,1,
 1,1,1,1,1,1,
 0,0,0,0,0,0,
 0,0,0,0,0,0};//运算符比较结果,若小于则为0

bool judgeopt(char c)
{
 bool result=false;
 for(int k=0;k<optsize;k++)
 {
  if(c==opt[k]) result=true;
 }
 return result;
}//判断是否为运算符


int rnt(char c)
{
 for(int i=0;i<optsize;i++)
 {
  if(c==opt[i])
   return i;
 }
 return 0;
}//返回运算符下标

double calculate(double a,double b,char c)
{
 switch(c)
 {
 case '+':return a+b;break;
 case '-':return a-b;break;
 case '*':return a*b;break;
 case '/':return a/b;break;
 default: return 0;
 }
}


int rnt_optcmp(int a,int b)
{
 return optcmp[a][b];
}//返回比较结果

 
int main()
{
 char str[100];
 char c;
 stack<double> sopd;
 stack<char> sopt;

 while(!sopd.empty()) sopd.pop();
 
 sopt.push('#');
 while(scanf("%s",str)!=EOF)
 {
  
  
  for(int j=0;str[j]!='='||sopt.top()!='#';j++)//**控制循环的关键**
  {
   c=str[j];
   if(!judgeopt(c))//如果不是运算符
   {
   
    
   double data=c-'0';//******************把数字字符转换为其表示的数字,再压入数字栈**************
   sopd.push(data);
   }
   else
   {
    if(rnt_optcmp(rnt(c),rnt(sopt.top()))==1)//c优先级大于栈顶运算符
    {
     sopt.push(c);
    }
    else
    {
     
     double c_a=sopd.top();
     sopd.pop();
     double c_b=sopd.top();
     sopd.pop();
     double c_c=calculate(c_b,c_a,sopt.top());
     sopd.push(c_c);
     sopt.pop();
     if(c!='=')//若为'=',注意不要压入栈
     {
      sopt.push(c);
      
     }
     else j--;//*************使str[j]停留在‘=’这里,省去对str[]的'='初始化。(小技巧)**********
    }
    
   }
   
  }
  
  
  printf("%lf",sopd.top());
  
  
  
 }
 
 return 0;
 
}

 


 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!