[保研/考研机试] KY129 简单计算器 浙江大学复试上机题 C++实现

描述

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

输入描述:

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

输出描述:

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

样例输入:

cpp 复制代码
输入:
1 + 2
4 + 2 * 5 - 7 / 11
0

样例输出:

cpp 复制代码
输出:
3.00
13.36

思路:

①设立运算符和运算数两个栈,,一个用来存储运算符,另一个用来存储运算数。

②在运算符栈中放置一个特殊运算符#,其优先级最低。

③将表达式尾部添加一个特殊运算符$,其优先级次低。

④从左至右依次遍历字符串,若遍历到运算符,则将其与运算符栈的栈顶元素进行比较,若运算符栈的栈顶的优先级小于该运算符,则将该运算符压入运算符栈;若运算符栈的栈顶的优先级大于该运算符,则弹出该栈顶运算符,从运算数栈中依次弹出运算数,完成弹出运算符对应的运算后,再将该结果压入运算数栈。

⑤若遍历到表达式中的运算数,则直接压入运算数栈。

⑥若运算符栈中仅剩两个特殊运算符#和$,则表达式运算结束,此时运算数栈中唯一的数字就是表达式的值。

源代码:

cpp 复制代码
#include<iostream>
#include<stack>
#include<map>
#include<string>
using namespace std;


//例题5.6 KY129 简单计算器
//考虑到需要计算的数字可能不止一位,就从检测到数字的索引开始,一直到检测不到数字的索引,这之间的就是一整个数字
double getNum(string str, int& index) {
	double res = 0;
	while (isdigit(str[index])) {
		res = res * 10 + str[index] - '0';
		index++;
	}
	return res;
}

//对两个数字进行运算
double cal(double x, double y, char op) {
	if (op == '+') {
		return x + y;
	}
	else if (op == '-') {
		return x - y;
	}
	else if (op == '*') {
		return x * y;
	}
	else if (op == '/') {
		return x / y;
	}
	return 0;
}

int main()
{
	//存储多个运算符号的优先级
	map<char, int> maps = { {'#',0},{'$',1},{'-',2},{'+',2}, {'/',3},{'*',3} };
	string s;
	//因为需要运算的式子可能不止一条,这里用while循环
	//因为输入的式子中可能包含多个空格,直接用getline(cin, s)回去整行的字符串,并赋值给s
	while (getline(cin, s)) {
		if (s == "0") { //结束条件
			break;
		}
		stack<char> symbol;  // 存储运算符的栈
		stack<double> number; // 存储操作数的栈
		int index = 0; //对字符串遍历的索引
		symbol.push('#'); //把'#'压入符号中,优先级最低
		s = s + '$'; //先把'$'放到要处理的公式字符串的末尾,优先级次低
		while (index < s.size()) { //遍历公式中的每一个字符
			//获取该数字索引开始的整个数字,并压入栈number中
			if (isdigit(s[index])) { 
				number.push(getNum(s, index));
			}
			//遇到公式中的空格直接跳过
			else if (s[index] == ' ') {
				index++;
			}
			else {
				//若运算符栈的栈顶的优先级小于遍历遇到的当前的运算符,则将该运算符压入运算符栈
				if (maps[s[index]] > maps[symbol.top()]) {
					symbol.push(s[index]);
					index++;
				}
				//否则,弹出该栈顶运算符,从运算数栈中依次弹出运算数,完成弹出运算符对应的运算后,再将该结果压入运算数栈。
				else {
					double x = number.top();
					number.pop();
					double y = number.top();
					number.pop();
					char op = symbol.top();
					symbol.pop();
					number.push(cal(y, x, op));
				}
			}
		}
		//精确到小数点后2位
		printf("%.2f\n", number.top());
	}

	return 0;
}

提交结果:

相关推荐
WG_175 分钟前
C++多态
开发语言·c++·面试
浅念同学12 分钟前
算法.图论-并查集上
java·算法·图论
何不遗憾呢20 分钟前
每日刷题(算法)
算法
立志成为coding大牛的菜鸟.25 分钟前
力扣1143-最长公共子序列(Java详细题解)
java·算法·leetcode
鱼跃鹰飞25 分钟前
Leetcode面试经典150题-130.被围绕的区域
java·算法·leetcode·面试·职场和发展·深度优先
liangbm331 分钟前
数学建模笔记——动态规划
笔记·python·算法·数学建模·动态规划·背包问题·优化问题
潮汐退涨月冷风霜36 分钟前
机器学习之非监督学习(四)K-means 聚类算法
学习·算法·机器学习
B站计算机毕业设计超人42 分钟前
计算机毕业设计Python+Flask微博情感分析 微博舆情预测 微博爬虫 微博大数据 舆情分析系统 大数据毕业设计 NLP文本分类 机器学习 深度学习 AI
爬虫·python·深度学习·算法·机器学习·自然语言处理·数据可视化
羊小猪~~1 小时前
深度学习基础案例5--VGG16人脸识别(体验学习的痛苦与乐趣)
人工智能·python·深度学习·学习·算法·机器学习·cnn
Charles Ray2 小时前
C++学习笔记 —— 内存分配 new
c++·笔记·学习