[C ++] 2つのスタックを持つ計算機を実装する

2つのスタックを備えた計算機の実装-プログラミング

文字列が妥当かどうかは判断されません。

規則:2つのスタック、数値スタックと演算子スタックを作成します。
トラバース文字列算術式: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.トラバースした演算子レベルを演算子スタックの最上位要素と比較します。現在の演算子レベルがスタックの最上位要素よりも小さい場合は、2つの数値スタックと1つの演算子スタックをポップして算術演算を実行します。行ったり来たり。最後に、現在の文字をオペレータースタックにプッシュします

7.算術文字列をトラバースした後、最後に演算子スタックが空であるか空ではないかを判断し、計算を実行します。

図5および6は、以下のように詳細に説明される:

「1+ 2 + 3 + 4」を実行する場合:
ここに画像の説明を挿入
最初の3文字をトラバースする場合、ルール1と3を使用して操作を実行すると、結果は上図のようになります。
ここに画像の説明を挿入
4番目の文字「+」に移動するときは、ルール2と6を使用して実行すると、結果は次の図のようになります。
ここに画像の説明を挿入
同じことが当てはまり、結果は次の図のようになります。これ以上の説明はありません。
ここに画像の説明を挿入

ここに画像の説明を挿入

ルール7を使用すると、最終結果は10になります。
ここに画像の説明を挿入

「1+ 2 * 3 + 4」を実行する場合:
ここに画像の説明を挿入
最初の3文字をトラバースする場合、ルール1と3を使用して操作を実行すると、結果は上図のようになります。

ここに画像の説明を挿入
4番目の文字「*」に移動するときは、ルール2、6を使用して実行すると、結果は次のようになります。
ここに画像の説明を挿入
ここに画像の説明を挿入

ここに画像の説明を挿入
ここに画像の説明を挿入

ここに画像の説明を挿入
最後に、文字列をトラバースした後、ルール7を使用して、次の図に示すように結果を実行します。
ここに画像の説明を挿入


ここに画像の説明を挿入
最初の3文字をトラバースするときに「1+ 2 *(3 + 4 * 5)」を実行する場合は、ルール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;
}

テスト:

#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