简单计算器

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

  

 #include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<stack>
using namespace std;
#define N 60010
stack<double>num; double arr1[]; //存储数字的栈,arr1[]存贮分离出来的数字
stack<char>op;double arr2[]; //存贮运算符的栈 ,arr2存贮分离出来的运算符 int pos1,pos2; //pos1和POS2分别表示arr1和arr2的长度
char str[]; //输入数据时的原字符串 void fact1() //將字符串中的數字和运算符提取出来存放进数组里
{
int i=;
int len=strlen(str);
pos1=pos2=;
while(i<len)
{
while(i<len&&str[i]==' ')i++; //处理空格
if(i==len)break;
if(str[i]>=''&&str[i]<='') //分离数字(比如1234,1后面肯定是数字,4后面不是数字)
{
double sum=0.0;
for(; i<len&&str[i]>=''&&str[i]<=''; i++)
sum=sum*10.0+str[i]-'';
arr1[pos1++] = 1.0*sum;
}
else //分离字符
{
arr2[pos2++]=str[i++];
}
}
}
void solve()
{
fact1(); //处理字符串
char nowop;
int p1=; //指向arr1的要使用时的数字下标,初始时为0表示最早从arr1【0】开始
int p2=; //指向arr2的要使用时的字符的下标,
num.push(arr1[p1++]);
op.push(arr2[p2++]);
while(p1<pos1||p2<pos2||num.size()>=) //判断循环条件
{
while(num.size()<&&p1<pos1) //维持数字栈中保留两个
num.push(arr1[p1++]);
if(p2<pos2&&op.empty()) //维持运算符栈中保留1个运算符
op.push(arr2[p2++]); if(op.top()=='*'||op.top()=='/') //直接可以进行运算,如3*7/8+4 时,3*7可直接算
{
double n1,n2;
n1=num.top();num.pop();
n2=num.top();num.pop();
nowop=op.top();op.pop();
if(nowop=='*')
num.push(n2*n1);
else
num.push(n2/n1);
}
//栈外的运算符级别高,例如3+5*8时,‘’*‘’级别大于‘’+‘’
else if(p2<pos2&&(nowop=arr2[p2])&&(nowop=='*'||nowop=='/')&&(op.top()=='+'||op.top()=='-'))
{
double s1;
if(nowop=='*')
s1=num.top()*arr1[p1++];
else
s1=num.top()/arr1[p1++];
num.pop();
num.push(s1);
p2++; //运算符数组指向下一位
}
else //栈外的运算符等级与栈内相等,或者无运算符,例如5+9-6,’-‘号相对’+‘平级
{
double n1,n2;
n1=num.top();num.pop();
n2=num.top();num.pop();
nowop=op.top();op.pop();
if(nowop=='-')
num.push(n2-n1);
else
num.push(n1+n2);
}
}
printf("%.2lf\n",num.top());
}
int main()
{
while(gets(str),str[]!=''||strlen(str)!=)
//谨防样例:0+0(也就说以0开头的式子也合法,这时需要再判一下长度!)
{
while(!num.empty())
num.pop();
while(!op.empty())
op.pop();
solve();
}
return ;
}

HDU-1237- 简单计算器--栈的基本应用的更多相关文章

  1. HDU 1237 简单计算器 栈

    额,题目是中文的,题意就不用说了= =都看懂喽.写个字符串先把这行计算式存进去,不过不能存一个算一个,因为考虑到乘除法比加减法优先的原则,如果是加号减号就先存着等待计算,如果是乘号除号就直接算出来值就 ...

  2. hdu 1237 简单计算器

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1237 简单计算器 Description 读入一个只包含 +, -, *, / 的非负整数计算表达式, ...

  3. hdu 1237 简单计算器(栈处理)

    简单计算器 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  4. HDU 1237 简单计算器(栈+stringstream)

    提供几份代码,这题的输入可以用stringsteam处理,先处理乘除后处理加减,正常思路,但是后面统计加减法的时候,对栈的运用错了,我用的时候相当于给它多加了几个括号就错了. 正确的简单解法就是,加法 ...

  5. hdu 1237 简单计算器 (表达式求值)【stack】

    <题目链接> 题目大意: 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值.  Input测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符, ...

  6. hdu-1237简单计算器(栈的运用)

    http://acm.hdu.edu.cn/showproblem.php?pid=1237 简单的栈的运用. 首先将数字和运算符分离,分别保存在两个数组中,然后按原来的式子的顺序,首先将第一个数和第 ...

  7. hiho #1332 : 简单计算器 栈+递归

    #1332 : 简单计算器 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 编写一个程序可以完成基本的带括号的四则运算.其中除法(/)是整除,并且在负数除法时向0取整.( ...

  8. hdoj 1237 简单计算器

    简单计算器 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  9. F - 简单计算器(栈)

    F - 简单计算器 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Descripti ...

  10. HDU1237 简单计算器 栈

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1237 题目大意:读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值. 题目分 ...

随机推荐

  1. .Net Core 2.2 项目部署到IIS

    1.安装IIS所需的Host扩展 从官网(https://dotnet.microsoft.com/download/dotnet-core/2.2)下载对应的.net core版本的Runtime ...

  2. 【OpenGL开发】关于GLEW扩展库

    GLEW是一个跨平台的C++扩展库,基于OpenGL图形接口.使用OpenGL的朋友都知道,window目前只支持OpenGL1.1的涵数,但 OpenGL现在都发展到2.0以上了,要使用这些Open ...

  3. 按键板的原理和实现--基于GPIO的按键板

    上篇介绍简单的ADC实现,需要IC提供一个额外的ADC.但出于IC成本的考虑,无法提供这个的ADC时,但提供了多个额外的GPIO(General Purpose Input Output:双向的:可以 ...

  4. [Asp.Net Core] - 使用 ViewComponents 实现分页控件

    分页控件(定义分页参数) ~/ViewComponents/PaginationViewComponent.cs using HelloWorld.DataContext; using Microso ...

  5. Linux 实现回收站功能脚本

    #!/bin/bash function z-trash() { # 判断参数是否为空 if [ ! $1 ] then echo "z-trash error: file name of ...

  6. STL源码剖析——空间配置器Allocator#3 自由链表与内存池

    上节在学习第二级配置器时了解了第二级配置器通过内存池与自由链表来处理小区块内存的申请.但只是对其概念进行点到为止的认识,并未深入探究.这节就来学习一下自由链表的填充和内存池的内存分配机制. refil ...

  7. Linux主要目录速查表

    /:根目彔.一般根目录下只存放目录,在linux下有且只有一个根目彔,所有的东西都是从这里开始 当在终端里输入/home.其实是在告诉电脑,先从/(根目录)开始,再进入到honie目录 /bin./u ...

  8. Spring AOP日志实现(一)

    前置通知:获取访问的类,访问的方法,带参数和不带参数的 日志表信息描述字段: 获取访问时长:

  9. 在uboot里面添加环境变量使用run来执行

    在uboot里面添加环境变量使用run来执行 本文链接:https://blog.csdn.net/u010979030/article/details/41038259 Author:杨正  Dat ...

  10. io.ByteIO和open操作二进制流的区别(转)

    转自Stack Overflow:https://stackoverflow.com/questions/42800250/difference-between-open-and-io-bytesio ...