【C++】用两个栈实现计算器

用两个栈实现计算器 - 程序设计

这里没判断字符串是否合理。

规则:建立两个栈,数字栈和操作符栈。
遍历字符串算术表达式:1+2*(3+4*5)
1.当遇到数字字符串直接将其转化为数字,压入数字栈中。
(考虑字符串“1234”如何转化为int型1234)。

2.给“+,-,,/,(,)”做一个等级划分。
unordered_map<char, int> map = { {’(’,0},{’+’,1},{’-’,1},{’
’,2},{’/’,2},{’)’,3} };

3.当遍历到第一个操作符字符时,就应该直接将其压入操作符栈中,(即判断遍历到第一个非数字字符且操作符栈为空,将其压入栈中)。

4.当遍历操作符字符是左括号时,将其直接压入栈中。

5.当遍历操作符是右括号时,即将括号内的算术表达式进行计算。(缩小为一个子问题)

6.将遍历的操作符等级与操作符栈顶元素作等级比较,若当前操作符等级比栈顶元素小,将数字栈弹出两个,操作符栈弹出一个,进行算术运算。循环往复。最后将当前字符压入操作符栈中

7.遍历完算术字符串后,最后判断操作符栈是否为空,不为空,进行计算。

5,6详细介绍如下图:

当执行 “1 + 2 + 3 + 4” :
在这里插入图片描述
当遍历前3个字符时,利用规则1,3执行操作,结果如上图。
在这里插入图片描述
当遍历到第四个字符’+’,利用规则2,6执行,结果如下图
在这里插入图片描述
同理,结果如下图,不再解释
在这里插入图片描述

在这里插入图片描述

利用规则7,最后结果为10
在这里插入图片描述

当执行“1 + 2 * 3 + 4”:
在这里插入图片描述
当遍历前3个字符时,利用规则1,3执行操作,结果如上图。

在这里插入图片描述
当遍历到第四个字符’*’,利用规则2,6执行,结果如下图
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
最后,遍历完字符串后,利用规则7,执行结果如下图
在这里插入图片描述

当执行"1 + 2 * (3 + 4 * 5)"
在这里插入图片描述
当遍历前3个字符时,利用规则1,3执行操作,结果如上图。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
最后就献上代码喽:

Calculator.h:

#pragma once
#include<iostream>
#include<stack>
#include<string>
#include<unordered_map>
using namespace std;
class Calculator
{
    
    
private:
	stack<int> numbers;
	stack<char>operators;
	string str;
	unordered_map<char, int>map;
public:
	Calculator();
	Calculator(string str);

	void set(string str);
	int get();
	int result();
	bool isdight(char c);

};

Calculator.cpp:

#include "Calculator.h"

Calculator::Calculator()
{
    
    
	map = {
    
     {
    
    '(',0},{
    
    '+',1},{
    
    '-',1},{
    
    '*',2},{
    
    '/',2},{
    
    ')',3} };
}

Calculator::Calculator(string str)
{
    
    
	map = {
    
     {
    
    '(',0},{
    
    '+',1},{
    
    '-',1},{
    
    '*',2},{
    
    '/',2},{
    
    ')',3} };
	set(str);
}

void Calculator::set(string str)
{
    
    
	this->str = str;
}

int Calculator::get()
{
    
    
	int i = 0, len = str.length();
	int priority_top, priority_cur;//记录栈顶操作符元素和当前操作符对应map大小
	while (i < len) {
    
    
		if (isdight(str[i])) {
    
    
			int sum = 0;
			while (i < len && isdight(str[i])) {
    
    
				sum = 10 * sum + (str[i] - '0');
				i++;
			}
			numbers.push(sum);
		}
		else {
    
    
			if (operators.empty()) {
    
    
				operators.push(str[i]);
				i++;
				continue;
			}
			priority_top = map[operators.top()];
			priority_cur = map[str[i]];
			if (priority_cur == 0) {
    
    
				operators.push(str[i]);
			}
			else if (priority_cur == 3) {
    
    
				while (operators.top() != '(') {
    
    
					numbers.push(result());
				}
				operators.pop();
			}
			else {
    
    
				while (!operators.empty() && priority_cur <= priority_top) {
    
    
					numbers.push(result());
					if (!operators.empty())
						priority_top = map[operators.top()];
				}
				operators.push(str[i]);
			}
			i++;

		}
		
	}
	while (!operators.empty()) {
    
    
		numbers.push(result());
	}
	int num = numbers.top();
	numbers.pop();
	return num;
}

int Calculator::result()
{
    
    
	int b = numbers.top();
	numbers.pop();
	int a = numbers.top();
	numbers.pop();
	char c = operators.top();
	operators.pop();
	switch (c) {
    
    
	case '+':
		return a + b;
	case '-':
		return a - b;
	case '*':
		return a * b;
	case '/':
		return a / b;
	}
}

bool Calculator::isdight(char c)
{
    
    
	if (c <= '9' && c >= '0') {
    
    
		return true;
}
	return false;
}

test:

#include<iostream>
using namespace std;
#include"Calculator.h"
int main() {
    
    
	Calculator cal;
	cal.set("1+2*(3+4*5)");
	cout << cal.get();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_48180029/article/details/115217262