这里没判断字符串是否合理。
规则:建立两个栈,数字栈和操作符栈。
遍历字符串算术表达式: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;
}