[C++] Implement a calculator with two stacks

Implementing a calculator with two stacks-programming

It is not judged whether the string is reasonable.

Rule: Create two stacks, a number stack and an operator stack.
Traverse string arithmetic expressions: 1+2*(3+4*5)
1. When a number string is encountered, it is directly converted into a number and pushed into the number stack.
(Consider how the string "1234" is converted to int type 1234).

2. Make a level division
for "+, -, ,/, (,)". unordered_map<char, int> map = {{'(',0},{'+',1},{'-',1},{' ',2},{'/',2},{' )',3} };

3. When the first operator character is traversed, it should be pushed directly into the operator stack, (that is, it is judged that the first non-numeric character is traversed and the operator stack is empty, and it is pushed onto the stack) .

4. When the traversal operator character is the left parenthesis, push it directly onto the stack.

5. When the traversal operator is the closing parenthesis, the arithmetic expression in the parentheses is calculated. (Reduced to a sub-problem)

6. Compare the traversed operator level with the top element of the operator stack. If the current operator level is smaller than the top element of the stack, pop two numbers from the stack and one pop from the operator stack to perform arithmetic operations. Back and forth. Finally, push the current character into the operator stack

7. After traversing the arithmetic string, finally judge whether the operator stack is empty, not empty, and perform calculations.

5 and 6 are described in detail as follows:

When executing "1 + 2 + 3 + 4":
Insert picture description here
When traversing the first 3 characters, use rules 1 and 3 to perform the operation, and the result is as shown in the figure above.
Insert picture description here
When traversing to the fourth character'+', use rules 2 and 6 to execute, and the result is as shown in the figure below. The
Insert picture description here
same is true, and the result is as shown in the figure below.
Insert picture description here

Insert picture description here

Using rule 7, the final result is 10
Insert picture description here

When executing "1 + 2 * 3 + 4":
Insert picture description here
When traversing the first 3 characters, use rules 1 and 3 to perform the operation, and the result is as shown in the figure above.

Insert picture description here
When traversing to the fourth character'*', use rules 2, 6 to execute, and the result is as shown below
Insert picture description here
Insert picture description here

Insert picture description here
Insert picture description here

Insert picture description here
Finally, after traversing the string, use rule 7 to execute the result as shown in the figure below
Insert picture description here

When executing "1 + 2 * (3 + 4 * 5)"
Insert picture description here
when traversing the first 3 characters, use rules 1 and 3 to perform the operation, and the result is as shown in the figure above.
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here

Insert picture description here
Finally, I will present the code:

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;
}

Guess you like

Origin blog.csdn.net/weixin_48180029/article/details/115217262