收藏一份模板观察观察
逻辑应该是,低优先级进来应该促使高优先级的进行运算
class Solution {
public:
unordered_map<char,int> oper_pri = {
{'+',1},
{'-',1},
{'*',2},
{'/',2},
{'%',2},
{'^',3}
};
stack<char> opers;
stack<long long> nums;
int calculate(string s) {
nums.push(0);
int n = s.size();
for(int i=0; i<n; i++){
if(s[i]==' ') continue;
else if(s[i]=='(') {
opers.push('(');
if(s[i+1]=='-'){
i++;
nums.push(0);
opers.push('-');
}
}
else if(s[i]==')'){
while(opers.top()!='('){
cal();
}
opers.pop();
}
else if('0'<=s[i] && s[i]<='9'){
int l = i;
while(i+1<n && '0'<=s[i+1] && s[i+1]<='9')
i++;
nums.push(stoll(s.substr(l,i-l+1)));
}
else{
while(!opers.empty() && opers.top()!='(' && oper_pri[opers.top()] >= oper_pri[s[i]]){
cal();
}
opers.push(s[i]);
}
}
while(!opers.empty() && opers.top()!='('){
cal();
}
return nums.top();
}
void cal(){
long long b = nums.top(); nums.pop();
long long a = nums.top(); nums.pop();
char oper = opers.top(); opers.pop();
long long res;
switch (oper) {
case '+': res = a + b; break;
case '-': res = a - b; break;
case '*': res = a * b; break;
case '/': res = a / b; break;
case '%': res = a % b; break;
case '^': res = pow(a,b); break;
}
nums.push(res);
}
};
中缀转后缀表达式
class Solution224 {
private:
bool IsOperator(const string& s) const
{
return s == "+" || s == "-" || s == "*" || s == "/" || s == "(" || s == ")";
}
int Priority(const string& s) const
{
if (s == "*" || s == "/")
{
return 1;
}
else if (s == "+" || s == "-")
{
return 0;
}
else
{
return -1;
}
}
public:
int calculate(string s) {
vector<string> infix;
StrToVector(s, infix);
// for (string& i : infix)
// {
// cout << i << " ";
// }
// cout << endl;
stack<string> s1;
InfixToSuffix(infix, s1);
stack<long> res;
while (!s1.empty())
{
// cout << "curr " << s1.top() << endl;
if (!IsOperator(s1.top()))
{
res.push(stol(s1.top()));
}
else
{
long num2 = res.top();
res.pop();
long num1 = res.top();
res.pop();
long temp = 0;
if (s1.top() == "+")
{
temp = num1 + num2;
}
else if (s1.top() == "-")
{
temp = num1 - num2;
}
else if (s1.top() == "*")
{
temp = num1 * num2;
}
else
{
temp = num1 / num2;
}
res.push(temp);
// cout << num1 << s1.top() << num2 << " into " << temp <<" res.top() " << res.top() << endl;
}
s1.pop();
}
// cout << endl;
return res.top();
}
// 需要忽略空格
void StrToVector(const string& s, vector<string>& infix)
{
int n = s.size();
string num = "";
for (int i = 0; i < n; ++i)
{
if (s[i] == ' ')
{
continue;
}
if (s[i] >= '0' && s[i] <= '9')
{
if (i < n - 1 && s[i + 1] >= '0' && s[i + 1] <= '9')
{
num += s[i];
}
else
{
num += s[i];
infix.push_back(num);
num.clear();
}
}
else
{
infix.emplace_back(1, s[i]);
}
}
}
//中缀转后缀 s1运算符栈 s2中间结果栈
void InfixToSuffix(const vector<string>& infix, stack<string>& s1)
{
stack<string> s2;
int n = infix.size();
for (int i = 0; i < n; ++i)
{
if (IsOperator(infix[i]))
{
if (s1.empty() || infix[i] == "(")
{
s1.push(infix[i]);
}
else
{
if (infix[i] != ")")
{
// 优先级判断
while (!s1.empty() && Priority(s1.top()) >= Priority(infix[i]))
{
s2.push(s1.top());
s1.pop();
}
// 这里肯定是大于优先级了,所以入s2
s1.push(infix[i]);
}
else
{
// 遇到 )
while (!s1.empty() && s1.top() != "(")
{
s2.push(s1.top());
s1.pop();
}
// 弹出 s1的 (
s1.pop();
}
}
}
else
{
s2.push(infix[i]);
}
}
while (!s1.empty())
{
s2.push(s1.top());
s1.pop();
}
// cout << "s2 pop ";
while (!s2.empty())
{
// cout << s2.top() << " ";
s1.push(s2.top());
s2.pop();
}
// cout << endl;
}
};