[C ++] 두 개의 스택이있는 계산기 구현

두 개의 스택 프로그래밍으로 계산기 구현

문자열이 합리적인지 판단되지 않습니다.

규칙 : 두 개의 스택, 숫자 스택 및 연산자 스택을 만듭니다.
횡단 문자열 산술 표현식 : 1 + 2 * (3 + 4 * 5)
1. 숫자 문자열이 발견되면 직접 숫자로 변환되어 숫자 스택으로 푸시됩니다.
(문자열 "1234"가 int 유형 1234로 변환되는 방법을 고려하십시오.)

2. "+,- ,, /, (,)"에
대한 레벨 분할만듭니다. 무순 맵 <char, int> map = {{ '(', 0}, { '+', 1}, { '-', 1}, { ' ', 2}, { '/', 2}, { ' )',삼} };

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을 사용하여 아래 그림과 같이 결과를 실행합니다.
여기에 사진 설명 삽입


여기에 사진 설명 삽입
처음 3 개의 문자를 순회 할 때 "1 + 2 * (3 + 4 * 5)" 를 실행하는 경우 규칙 1과 3을 사용하여 연산을 수행하면 결과는 위 그림과 같습니다.
여기에 사진 설명 삽입
여기에 사진 설명 삽입
여기에 사진 설명 삽입
여기에 사진 설명 삽입
여기에 사진 설명 삽입
여기에 사진 설명 삽입

여기에 사진 설명 삽입
마지막으로 코드를 제시하겠습니다.

계산기 .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;
}

테스트:

#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