教你用栈做一个 《神》计算器
  • 板块学术版
  • 楼主AKPC
  • 当前回复21
  • 已保存回复21
  • 发布时间2022/5/31 16:38
  • 上次更新2023/10/28 00:13:19
查看原帖
教你用栈做一个 《神》计算器
540363
AKPC楼主2022/5/31 16:38

计算器,就是输入一个式子算出结果
由于涉及四则运算+乘方+括号,分了级别,所以不能顺序渐进,必须要有顺序。例如

3+5*9=3+45=48   //正确
3+5*9=8*9=72   //错误,应该先算乘号,运算级别更优先

如果顺序错了,差距就很大了,另外有无括号的区别也很大

(3+5)*9=8*9=72   //这里有括号,所以是正确的,没括号就错了

在这之前,我们可以先写一个运算两个的函数。这样会简单易懂。

int level(char c) {
	if (c == '+' || c == '-') return 1;
	if (c == '*' || c == '/') return 2;	
	if (c == '^') return 3;
	return 0;
}
void calculation() {
	int a = digit.top();
	digit.pop();
	int b = digit.top();
	digit.pop();
	char ch = symbol.top();
	symbol.pop(); 
	if (ch == '+') digit.push(a + b);
	else if (ch == '-') digit.push(b - a);
	else if (ch == '*') digit.push(a * b);
	else if (ch == '/') digit.push(b / a);
	else if (ch == '^') digit.push(pow(b, a));
}

那么,因为有运算符,我们可以用字符串的方式,输入后,挨个存
这时候就有大聪明要问了:你挨个存不全变成个位数了吗?其实,我们可以等到运算符出现时再将整个数存放

for (int i = 0; i < len; i ++) {
	if (str[i] >= '0' && str[i] <= '9') {
		x = x*10 + str[i]-'0';
		tag = true;
	}
	else {
		if (tag) {
			digit.push(x);
			tag = false;
			x = 0;
		}
		if (str[i] == '(') {
			symbol.push(str[i]);
			continue;
		}
		if (str[i] == ')') {
			while (symbol.top() != '(') 				calculation();
			symbol.pop();
			continue;
		}
		while (!symbol.empty() &&level(symbol.top()) >= level(str[i])) 					calculation();
			symbol.push(str[i]);
		}
	}

因为要清空栈,所以还不够,必须还要再写这一步:

if (tag) digit.push(x);
while (!symbol.empty()) calculation();

都讲到这里了,最后来看爆肝代码吧

#include <bits/stdc++.h>
using namespace std;
stack <long long> digit;
stack <char> symbol;
int level(char c) {
	if (c == '+' || c == '-') return 1;
	if (c == '*' || c == '/') return 2;	
	if (c == '^') return 3;
	return 0;
}
void calculation() {
	int a = digit.top();
	digit.pop();
	int b = digit.top();
	digit.pop();
	char ch = symbol.top();
	symbol.pop(); 
	if (ch == '+') digit.push(a + b);
	else if (ch == '-') digit.push(b - a);
	else if (ch == '*') digit.push(a * b);
	else if (ch == '/') digit.push(b / a);
	else if (ch == '^') digit.push(pow(b, a));
}
int main()
{
	string str;
	cin >> str;
	int len = str.length();
	int x = 0;
	bool tag = false;
	for (int i = 0; i < len; i ++) {
		if (str[i] >= '0' && str[i] <= '9') {
			x = x*10 + str[i]-'0';
			tag = true;
		}
		else {
			if (tag) {
				digit.push(x);
				tag = false;
				x = 0;
			}
			if (str[i] == '(') {
				symbol.push(str[i]);
				continue;
			}
			if (str[i] == ')') {
				while (symbol.top() != '(') 				calculation();
				symbol.pop();
				continue;
			}
			while (!symbol.empty() && level(symbol.top()) >= level(str[i])) 					calculation();
			symbol.push(str[i]);
		}
	}
	if (tag) digit.push(x);
	while (!symbol.empty()) calculation();
	cout << digit.top() << endl;
	return 0;
}

好了,你可以自己试试,真的很实用,快速得结果!

2022/5/31 16:38
加载中...