using System;
using System.Collections.Generic;
class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 返回表达式的值
* @param s string字符串 待计算的表达式
* @return int整型
*/
Stack<Char> ops = new Stack<char>();
Stack<int> nums = new Stack<int>();
Dictionary<char, int> D = new Dictionary<char, int>();
public Solution()
{
D.Add('(', 1);
D.Add('+', 3);
D.Add('-', 3);
D.Add(')', 4);
D.Add('s', 5);
D.Add('@', 0); //乘以10的运算
D.Add('*', 2);
}
public int solve(string s)
{
// write code here
ops.Clear();
nums.Clear();
for (int i = 0; i < s.Length; i++)
{
if (i == s.Length - 1)
handle(s[i], 's');
else
handle(s[i], s[i + 1]);
}
while(nums.Count>1)
{
Shrink();
}
return nums.Pop();
}
public void handle(char c, char next)
{
if (c >= '0' && c <= '9')
{
//是连续两个数字
if (next >= '0' && next <= '9')
{
int newC = -1000;
if (ops.Count > 0 && ops.Peek() == '@')
{
newC = Cal(nums.Pop(), c - '0', ops.Pop());
nums.Push(newC);
ops.Push('@');
}
else
{
nums.Push(c - '0');
ops.Push('@');
}
return;
}
//不是连续两个数字
if (nums.Count > 0 && ops.Count > 0)
{
if (D[next] >= D[ops.Peek()] && ops.Peek()!='(')
{
int start = nums.Pop();
int end = c - '0';
char op = ops.Pop();
int num = Cal(start, end, op);
nums.Push(num);
while(ops.Count>0&& D[next]>=D[ops.Peek()] && nums.Count>=2 && ops.Peek()!='(')
{
Shrink();
}
return;
}
}
nums.Push(c - '0');
// ops.Push()
return;
}
if (c == '+' || c == '-' || c == '*' || c == '(')
{
ops.Push(c);
}
if (c == ')')
{
//int start, end, num;
//char op;
while (ops.Peek() != '(')
{
//end = nums.Pop();
//op = ops.Pop();
//start = nums.Pop();
//num = Cal(start, end, op);
//nums.Push(num);
Shrink();
}
ops.Pop();
}
}
private void Shrink()
{
int start, end, num;
char op;
end = nums.Pop();
op = ops.Pop();
start = nums.Pop();
num = Cal(start, end, op);
nums.Push(num);
}
private int Cal(int s, int e, char op)
{
switch (op)
{
case '+':
return s + e;
case '-':
return s - e;
case '*':
return s * e;
case '@':
return s * 10 + e;
default:
return int.MinValue;
}
}
}
写的有点混乱,但是思路应该很容易理解:
1. 要定义非字母符号的优先级
2. 考虑到数字不是个位,因为这里添加了‘@’符号,如果一个数a后面仍然是数b,那么插入下一个数时,会取出上一个数进位,将1*10+b放入;但是如果首位时两个数字,那么第一个无法进位,这里表现为一个判断
3.每次输入数字时,会进行判断,如果数字后面的字符优先级不高于栈定符号的优先级,那么就进行运算:1+2+3,到2的时候,发现第二个加号优先级不高于1,故先将见面的计算出来,将数字入栈
4.如果后面的优先级高于栈顶的优先级 ,那么只能先将数字存入,后面在算 :例如 1+2*3 ,到2的时候只能先存入
5.考虑到括号存在,“("优先级高于任何算数,只能因”)“出现而成对销毁
6. shrink函数是收缩的意思,九世纪因为后面某个运算成功,导致前面一堆可以计算时,就先计算,例如 (1-(2-(10+3*4)))*5-6, 当最内的3*4计算完得到12入nums栈,但此时可以继续计算 10+12操作,这里就会调用Shrink函数,但是”(“运算符优先级高,不能拿出来运算
7.因为每次要传入当前字符和下一个字符,因此在最后一个字符遍历时,它的下一个字符手动设为”s',



京公网安备 11010502036488号