简易计算器(栈与队列的使用)

题目描述

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

输入

测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。

输出

对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。

样例输入

30 / 90 - 26 + 97 - 5 - 6 - 13 / 88 * 6 + 51 / 29 + 79 * 87 + 57 * 92
0

解题思路:本题主要是对栈与队列的使用完成对计算器的模拟。解题主要分为两步,(1)中缀表达式转化为后缀表达式。(2)计算后缀表达式。计算中缀表达式:如果当前字符是数字则将其插入队列中,如果是运算符,与栈中运算符比较优先级,如果优先级高直接压入栈中,否则将栈中运算符出栈压入队列中。计算后缀表达式:如果队首元素是数字则入栈,若是运算符则从栈中弹出两个数字,将计算结果压入栈中。

#include<cstdio>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
using namespace std; 
struct node
{
	double num;
	char op;
	bool flag;  //true 为数字 
};
stack<node> st;
queue<node> q;
map<char,int> mp;
string str;
void Change()  //中缀转后缀 
{
	node temp,tempst;       //temp用于存队首元素,tempst存栈顶元素 
	for(int i = 0;i < str.length();)
	{
		if(str[i]>='0'&&str[i]<='9')  //如果是数字 
		{
			temp.num = str[i] - '0';
			temp.flag = true;
			i++;
			while(i < str.length() && str[i]>='0' && str[i] <= '9')  //数字可能不止一位 
			{
				temp.num = temp.num * 10 + str[i] - '0';
				i++;
			}
			q.push(temp);
		}
		else				//是运算符 
		{
			temp.op = str[i];
			temp.flag = false;
			if(!st.empty())
				tempst = st.top();
			while(!st.empty() && mp[temp.op] <= mp[tempst.op]) //与栈顶运算符优先级比较
			{									// 只有优先级大于栈顶操作符才直接入栈,否则将栈中操作符压入队列 
				q.push(tempst);
				st.pop();
				if(!st.empty())
				{
					tempst=st.top();
				}
			}
			st.push(temp);
			i++;
		}
	}
	while(!st.empty())
	{
		q.push(st.top());
		st.pop();
	}	
}

double Cal ()			//计算 
{
	double num1,num2,num;
	node temp,tempst;
	while(!q.empty())
	{
		temp = q.front();
		if(temp.flag == true)			//队首是数字,压入栈zhong 
		{
			st.push(temp);
		}
		else							//是运算符,从栈中弹出两个数字 
		{
			tempst = st.top();
			num2 = tempst.num;
			st.pop();
			tempst = st.top();
			num1 = tempst.num;
			st.pop();
			if(temp.op == '+')	num = num1 + num2;
			else if(temp.op == '-') num = num1 - num2;
			else if(temp.op == '*') num = num1 * num2;
			else if(temp.op == '/') num = num1 / num2;
			temp.num = num;
			temp.flag = true;
			st.push(temp);
		}
		q.pop();
	}
	temp = st.top();
	return temp.num;
}
int main(void)
{
	mp['+'] = mp['-'] = 0;
	mp['*'] = mp['/'] = 1;
	double num;
	while(getline(cin,str),str!="0")
	{
		for(string::iterator it = str.begin();it!=str.end();it++)
		{
			if(*it == ' ')
				str.erase(it);
		}
		while(!st.empty())
			st.pop();
		Change();
		num = Cal();
		printf("%.2f\n",num);
	}
	return 0;
}

总结:本题两次对栈使用,第一次用于放运算符,第二次用于放数字。

发布了24 篇原创文章 · 获赞 1 · 访问量 504

猜你喜欢

转载自blog.csdn.net/lovingcgq/article/details/104361915