题目1019:简单计算器(栈的应用)

题目1019:简单计算器

时间限制:1 秒

内存限制:32 兆

特殊判题:

提交:10054

解决:3669

题目描述:
    读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
输入:
    测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
输出:
    对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
样例输入:
1 + 2
4 + 2 * 5 - 7 / 11
0
样例输出:
3.00
13.36
来源:
2006年浙江大学计算机及软件工程研究生机试真题
答疑:
解题遇到问题?分享解题心得?讨论本题请访问: http://t.jobdu.com/thread-7743-1-1.html

思路:就是简单栈的使用,用到二个栈,分别是数字栈和符号栈;我这里只是应用简单数组实现栈的操作,但是这里有一个 特别需要注意的就是:在读取到乘法符号或者除法符号时,需要再进行读取一次数字才能进行算数运算。我写的代码如下:
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
using namespace std;
double s_num[200];		//数字栈-用来存放中间数字结果的 
char s_char[200];		//字符栈-用来存放字符串里的每一个字符 
int main()
{
	ifstream in;
	in.open("5.txt");
	string str;
	getline(in,str);		//读取一行算数表达式 
	while(str!="0")			//这里用简易的数组实现栈很关键 
	{
		int top1=-1;		//二个栈顶指针 
		int top2=-1; 
		int index=0;		//字符串的下标 
		int num=0;			//中间数字结果 
		int count=0;		
		while(index<str.length())
		{
			while(str[index]>='0' && str[index]<='9' && index<str.length())
			{
				num=num*10+str[index]-'0';
				++index;
			}
			
			s_num[++top1]=num;
			++index;
			if(index<str.length())				//这里运算符号进栈还要判断下标是否超出范围 
				s_char[++top2]=str[index];
				else ++top2;
			
			if(s_char[top2-1]=='*')				//每次判断到符号*,不能立马计算,因为此时乘数还没有进数字栈 
			{
				 s_num[top1-1]=s_num[top1-1]*s_num[top1];
				 s_char[top2-1]=s_char[top2];
				 --top1;
				 --top2;
			}else if(s_char[top2-1]=='/')
			{
				s_num[top1-1]=s_num[top1-1]/s_num[top1];
				s_char[top2-1]=s_char[top2];
				 --top1;
				 --top2;
			}
			index=index+2;
			num=0;
		}
		if(top1>0)			//此时运算符号栈只剩下+-了,从左到右进行运算即可 
		{
			int top=0;
			while(top<top1)
			{
				if(s_char[top]=='+')
				{
					s_num[top+1]=s_num[top]+s_num[top+1];
				 	++top;
				 	++top2;
				}else
				{
					s_num[top+1]=s_num[top]-s_num[top+1];
				 ++top;
				 ++top2;	
				}
			}

		}
		cout<<fixed<<setprecision(2)<<s_num[top1]<<endl;
		getline(in,str);
	}
	return 0;
}

(2)看了一下别人使用STL容器里的stack,感觉十分麻烦,主要是读取格式不太好,个人感觉读取一行数据比较简单,但还是附上别人的代码参考一下stack的使用。

#include <iostream>  
#include <iomanip>  
#include <stack>  
#include <stdlib.h>  
#include <stdio.h>  
  
using namespace std;  
  
int main()  
{  
    stack<double> SD; //数字栈  
    stack<char> SO;       //操作符栈  
    double left, right; //退栈时存储栈头数字  
    int num;    //输入数字  
    char op;    //输入操作符  
    double data[1000];  //数字数组  
    char operate[1000]; //操作符数组  
  
    while (cin>>num)  //读入开始数字  
    {  
        op = getchar(); //读取数字后输入的字符  
        if (num == 0 && op == '\n') //输入0后,退出  
        {  
            break;  
        }  
        SD.push(num);  
        while (op == ' ')   //数字后要跟空格  
        {  
            op = getchar(); //读取空格后的操作符  
            if (op == '\n') //输入回车后,程序结束  
            {  
                break;  
            }  
            if (!SO.empty() && (SO.top() == '*' || SO.top() == '/'))  
            {  
                right = SD.top();  
                SD.pop();  
                left = SD.top();  
                SD.pop();  
                if (SO.top() == '*')  
                {  
                    SD.push(left * right);  
                }  
                if (SO.top() == '/')  
                {  
                    SD.push(left / right);  
                }  
                SO.pop();  
            }  
            SO.push(op);  
            cin>>num;  
            SD.push(num);  
            op = getchar(); //下一轮循环判断  
  
        }  
        if (SO.top() == '*' || SO.top() == '/')  
        {  
            right = SD.top();  
            SD.pop();  
            left = SD.top();  
            SD.pop();  
            if (SO.top() == '*')  
            {  
                SD.push(left * right);  
            }  
            else if (SO.top() == '/')  
            {  
                SD.push(left / right);  
            }  
            SO.pop();  
        }  
      
  
        //将堆栈数据保存到保存到数组中,从左向右计算  
        int i = 0;  
        int oplength, datalength;   //栈内数据长度  
        int optop, datatop;  
        while (!SO.empty())  
        {  
            operate[i++] = SO.top();  
            SO.pop();  
        }  
        oplength = i;  
        optop = i - 1;  
        i = 0;  
        while (!SD.empty())  
        {  
            data[i++] = SD.top();  
            SD.pop();             
        }  
        datalength = i;  
        datatop = i - 1;  
  
        for (int j = optop; j >= 0; j--)  
        {  
            if (operate[j] == '+')  
            {  
                data[datatop - 1] = data[datatop] + data[datatop - 1];  
                datatop --;  
            }  
            else if (operate[j] == '-')  
            {  
                data[datatop - 1] = data[datatop] - data[datatop - 1];  
                datatop --;  
            }  
        }  
          
        cout.setf(ios::fixed);  
        cout<<setprecision(2)<<data[0]<<endl;  
    }  
    return 0;  
  
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值