算法笔记练习 6.7 stack 问题 A: 简单计算器(暴力遍历)

算法笔记练习 题解合集

本题链接

题目

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

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

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

样例输入

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

样例输出

12178.21

思路

标准解法的思路(中缀表达式转后缀,再计算)请参考算法笔记 P247,我实现标准解法的代码请点 问题 A: 简单计算器(标准解法)。


我写了半天中缀转后缀没写出来…于是用了暴力解法,把所有数字和运算符放进一个 vector 里面,第一次遍历计算所有的乘法和除法,第二次遍历计算所有的加法和减法。每次做运算的时候删除运算符及其两侧的数字,并将运算结果插入运算位置。

因为是在数组里操作的,导致时间复杂度是丧心病狂的 O ( n 2 ) O(n^2) O(n2) 哈哈哈哈哈,不过由于数据量小,蒙混过关吧,学到 P247 再啃标准解法。

代码

#include 
#include 
#include 
#include 
using namespace std;
struct Node {
	bool flag;
	double num;
	char op;
};
void doSomething(vector<Node>& ans, char doWhat1, char doWhat2) {
	for (int i = 0; i < ans.size(); ++i) {
		if (!ans[i].flag && (ans[i].op == doWhat1 || ans[i].op == doWhat2)) {
			double a = ans[i - 1].num, b = ans[i + 1].num;
			char op = ans[i].op;
			ans.erase(ans.begin() + i - 1, ans.begin() + i + 2);
			--i;
			Node temp;
			temp.flag = true;
			if 		(op == '+')	temp.num = a + b;
			else if (op == '-')	temp.num = a - b;
			else if (op == '*')	temp.num = a * b;
			else if (op == '/')	temp.num = a / b;
			ans.insert(ans.begin() + i, temp);
		} 
	} 
} 
int main() {
	int p, q;
	string input;
	vector<Node> ans; 
	while (getline(cin, input) && input != "0") {
		ans.clear();
		input += " ";
		p = 0;
		do {
			q = p;
			while (input[q] != ' ')
				++q;
			Node temp;
			if (isdigit((input.substr(p, q - p))[0])) {
				temp.flag = true;
				temp.num = stod(input.substr(p, q - p));
			} else {
				temp.flag = false;
				temp.op = (input.substr(p, q - p))[0];
			}
			ans.push_back(temp); 
			p = ++q;
		} while (q < input.size() - 1);
		doSomething(ans, '*', '/');
		doSomething(ans, '+', '-');
		printf("%.2lf\n", ans[0].num); 
	}
	return 0;
} 

你可能感兴趣的:(算法笔记,算法,c++,数据结构,c语言)