栈 简单计算器_27(表达式求值)

简单计算器
描述
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
输入描述:
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
输出描述:
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
示例
输入:
1 + 2
4 + 2 * 5 - 7 / 11
0
输出:
3.00
13.36
这个题有个比较坑的点,也是因为本人比较菜。。。做栈相关的题目还是多找几个例子在纸上先模拟一下比较好

新的运算符如果优先级和栈顶的运算符的优先级一样的话,要先算栈顶的运算符,这个原理其实就是在计算表达式的过程中对于优先级相同的要遵循从左往右计算的顺序。如果不这样算的话,对于栈,我们都知道,是后进先出,有逆序的特点,那么举个例子 3/1×3,如果除号入栈之后,乘号也入栈之后,那么弹栈的时候就是先计算1×3得3了,然后3/3=1,与原来的3/1×3=9的结果大不相同,相当于计算了3/(1×3),多给加了个括号,即证开始的规则

#include<bits/stdc++.h>
using namespace std;
//表达式求值
//这儿的下标i必须是引用类型
//因为需要不断获取下一位数字的下标
//而且此处的下标变了在main函数中的下标也要发生变化
//因此是引用类型 
int getnum(string str,int& i){
	double num=0;
	while(isdigit(str[i])){
		num=num*10+str[i]-'0';
		i++;
	}
	return num;
}
int getprior(char s){
	//#和$的优先级大小
	//#的优先级要比$小,如果#优先级高无法取操作数做#运算,因为#本身不是什么运算 
	//$的优先级次低是为了在字符串中最后一个操作数读入数据栈中之后
	//能够通过$与符号栈栈顶符号的不断比较, 最终完成运算
	//以上解释不明白的话,可以在纸上画出栈利用示例模拟一下就懂了
	//符号的优先级次序为 #$+-*/ 
	if(s=='#'){
		return 0;
	}
	else if(s=='$'){
		return 1;
	}
	else if(s=='+'||s=='-'){
		return 2;
	}
	else{
		return 3;
	}
}
double calculate(double data1,double data2,char ch){
	double data3;
	if(ch=='+'){
		data3=data1+data2;
	}
	else if(ch=='-'){
		data3=data1-data2;
	}
	else if(ch=='*'){
		data3=data1*data2;
	}
	else if(ch=='/'){
		data3=data1/data2;
	}
	return data3;
}
int main(){
	//两个栈,一个符号栈,一个运算数栈
	string str;
	while(getline(cin,str)){
		if(str=="0"){
			break;
		}
		stack<char> opr;
		stack<double> data;
		//运算符栈的底部是#
		opr.push('#');
		//字符串表达式的末尾是$,用来标志结束
		str+='$';
		int i=0;
		while(i<str.length()){
			if(str[i]==' '){
				i++;
			}
			else if(isdigit(str[i])){
				//是数字,但要考虑数字的位数 
				//入数据栈的必须是完整的数 
				data.push(getnum(str,i));
				//传的参数必须是整个字符串,因为需要进一步去找寻下一位数字 
			}
			else{
				//是运算符
				if(getprior(str[i])<=getprior(opr.top())){
					//如果新的运算符的优先级小于等于运算符栈顶的
					//先运算栈顶优先级高的 
					double data2=data.top();
					data.pop();
					double data1=data.top();
					data.pop();
					char ch=opr.top();
					double data3 = calculate(data1,data2,ch);
					data.push(data3);
					opr.pop();
				}
				else{
					//新的运算符的优先级大于运算符栈顶
					//直接入栈
					opr.push(str[i]);
					i++;
				}
				 
			}
		}
		cout<<fixed<<setprecision(2)<<data.top()<<endl;
	} 
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
MFC计算器可以通过使用实现表达式的求值。具体步骤如下: 1. 将中缀表达式转换为后缀表达式。 2. 创建一个,用来存储数字和运算符。 3. 从左到右扫描后缀表达式中的每个元素。 4. 如果元素是数字,则将其压入中。 5. 如果元素是运算符,则从中弹出两个数字进行运算,并将运算结果压入中。 6. 重复步骤 3 - 5,直到所有元素都被处理完毕。 7. 最后中只剩下一个元素,即为表达式的计算结果。 下面是一个简单的 MFC 计算器的代码,实现了上述步骤: ``` #include "stdafx.h" #include "ExpressionEvaluator.h" #include <stack> double ExpressionEvaluator::Evaluate(const CString& expression) { CString postfix = InfixToPostfix(expression); std::stack<double> stack; double result = 0.0; for (int i = 0; i < postfix.GetLength(); i++) { char c = postfix[i]; if (isdigit(c)) { stack.push(c - '0'); } else if (c == '+' || c == '-' || c == '*' || c == '/') { double a = stack.top(); stack.pop(); double b = stack.top(); stack.pop(); switch (c) { case '+': result = b + a; break; case '-': result = b - a; break; case '*': result = b * a; break; case '/': result = b / a; break; } stack.push(result); } } result = stack.top(); stack.pop(); return result; } CString ExpressionEvaluator::InfixToPostfix(const CString& expression) { CString postfix; std::stack<char> stack; for (int i = 0; i < expression.GetLength(); i++) { char c = expression[i]; if (isdigit(c)) { postfix += c; } else if (c == '(') { stack.push(c); } else if (c == ')') { while (!stack.empty() && stack.top() != '(') { postfix += stack.top(); stack.pop(); } if (!stack.empty() && stack.top() == '(') { stack.pop(); } } else if (c == '+' || c == '-' || c == '*' || c == '/') { while (!stack.empty() && GetPrecedence(c) <= GetPrecedence(stack.top())) { postfix += stack.top(); stack.pop(); } stack.push(c); } } while (!stack.empty()) { postfix += stack.top(); stack.pop(); } return postfix; } int ExpressionEvaluator::GetPrecedence(char c) { if (c == '+' || c == '-') { return 1; } else if (c == '*' || c == '/') { return 2; } else { return 0; } } ``` 其中,`Evaluate` 函数用于计算表达式的值,`InfixToPostfix` 函数用于将中缀表达式转换为后缀表达式,`GetPrecedence` 函数用于获取运算符的优先级。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

每天都要学算法(努力版)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值