文字列が妥当かどうかは判断されません。
規則: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;
}