• HDU1237 简单计算器栈的基本应用


    简单计算器

    Problem Description
    读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
     
    Input
    测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
     
    Output
    对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
     
    Sample Input
    1 + 2
    4 + 2 * 5 - 7 / 11 0
     
    Sample Output
    3.00 13.36
    ————————————————————————————————————————————————————分割线

    简单分析:

      栈的基本应用,模拟计算机的底层计算功能。非负整数表示0也可出现在表达式中,小数点后两位表示需要用double类型来存储数据。

      这类问题转化为后缀表达式来做,更常规正式点,编写速度更快;不过,我还是用基本两个栈的模拟,先大致理清几类思路,然后尝试编程,才测试各种自造地合理的尽可能全面的样例:哪里有bug就去补哪里。(如果思路没有理清,比较费时间吧!简单题貌似还好说!)

      代码里的注释给的比较详细,自己点开看看。给出下面几组参考数组,只要可以正确基本可以AC:

      1 + 2
      1 + 2 * 3 - 4 / 5
      1111+220/220*1+1*1*0
      2*2*2/8-4+5/5/5*5
      16*8/4+7-3/3*9
      0-8+9

      

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<math.h>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<stack>
      7 using namespace std;
      8 #define N 60010
      9 stack<double>num; double arr1[211];   //存储数字的栈,arr1[]存贮分离出来的数字
     10 stack<char>op;double arr2[211];     //存贮运算符的栈 ,arr2存贮分离出来的运算符
     11 
     12 int pos1,pos2;  //pos1和POS2分别表示arr1和arr2的长度
     13 char str[300];   //输入数据时的原字符串
     14 
     15 void fact1()  //將字符串中的數字和运算符提取出来存放进数组里
     16 {
     17     int i=0;
     18     int len=strlen(str);
     19     pos1=pos2=0;
     20     while(i<len)
     21     {
     22         while(i<len&&str[i]==' ')i++;  //处理空格
     23         if(i==len)break;
     24         if(str[i]>='0'&&str[i]<='9')  //分离数字(比如1234,1后面肯定是数字,4后面不是数字)
     25         {
     26             double sum=0.0;
     27             for(; i<len&&str[i]>='0'&&str[i]<='9'; i++)
     28                 sum=sum*10.0+str[i]-'0';
     29             arr1[pos1++] = 1.0*sum;
     30         }
     31         else             //分离字符
     32         {
     33             arr2[pos2++]=str[i++];
     34         }
     35     }
     36 }
     37 void solve()
     38 {
     39     fact1(); //处理字符串
     40     char nowop;
     41     int p1=0;  //指向arr1的要使用时的数字下标,初始时为0表示最早从arr1【0】开始
     42     int p2=0;  //指向arr2的要使用时的字符的下标,
     43     num.push(arr1[p1++]);
     44     op.push(arr2[p2++]);
     45     while(p1<pos1||p2<pos2||num.size()>=2)  //判断循环条件
     46     {
     47         while(num.size()<2&&p1<pos1) //维持数字栈中保留两个
     48             num.push(arr1[p1++]);
     49         if(p2<pos2&&op.empty())  //维持运算符栈中保留1个运算符
     50             op.push(arr2[p2++]);
     51 
     52         if(op.top()=='*'||op.top()=='/') //直接可以进行运算,如3*7/8+4 时,3*7可直接算
     53         {
     54                 double n1,n2;
     55                 n1=num.top();num.pop();
     56                 n2=num.top();num.pop();
     57                 nowop=op.top();op.pop();
     58                 if(nowop=='*')
     59                     num.push(n2*n1);
     60                 else
     61                     num.push(n2/n1);
     62         }
     63                 //栈外的运算符级别高,例如3+5*8时,‘’*‘’级别大于‘’+‘’
     64         else if(p2<pos2&&(nowop=arr2[p2])&&(nowop=='*'||nowop=='/')&&(op.top()=='+'||op.top()=='-'))
     65         {
     66                 double s1;
     67                 if(nowop=='*')
     68                     s1=num.top()*arr1[p1++];
     69                 else
     70                     s1=num.top()/arr1[p1++];
     71                 num.pop();
     72                 num.push(s1);
     73                 p2++; //运算符数组指向下一位
     74         }
     75         else    //栈外的运算符等级与栈内相等,或者无运算符,例如5+9-6,’-‘号相对’+‘平级
     76         {
     77             double n1,n2;
     78             n1=num.top();num.pop();
     79             n2=num.top();num.pop();
     80             nowop=op.top();op.pop();
     81             if(nowop=='-')
     82                 num.push(n2-n1);
     83             else
     84                 num.push(n1+n2);
     85         }
     86     }
     87     printf("%.2lf\n",num.top());
     88 }
     89 int main()
     90 {
     91     while(gets(str),str[0]!='0'||strlen(str)!=1)
     92         //谨防样例:0+0(也就说以0开头的式子也合法,这时需要再判一下长度!)
     93     {
     94         while(!num.empty())
     95             num.pop();
     96         while(!op.empty())
     97             op.pop();
     98         solve();
     99     }
    100     return 0;
    101 }
    View Code
    你不逼自己一把,你永远都不知道自己有多优秀!只有经历了一些事,你才会懂得好好珍惜眼前的时光!
  • 相关阅读:
    EasyNVR摄像机网页无插件直播方案H5前端构建之:通道内部搜索功能的实现方案与代码
    EasyNVR摄像机网页无插件直播方案H5前端构建之:bootstrap弹窗功能的实现方案与代码
    EasyNVR摄像机网页无插件直播方案H5前端构建之:bootstrap-datepicker日历插件的实时动态展现
    EasyNVR摄像机网页无插件直播方案H5前端构建之:如何播放HLS(m3u8)直播流
    EasyNVR摄像机网页无插件直播方案H5前端构建之:区分页面是自跳转页面还是分享页面
    EasyNVR摄像机网页无插件直播方案H5前端构建之:如何区分PC端和移动端
    EasyDSS高性能流媒体服务器开发RTMP直播同步输出HLS(m3u8)录像功能实现时移回放的方案
    Stack Overflow: The Architecture
    The week in .NET
    十分钟轻松让你认识Entity Framework 7
  • 原文地址:https://www.cnblogs.com/zhazhaacmer/p/8376045.html
Copyright © 2020-2023  润新知