using System;
using System.Collections.Generic;
using System.Text;
namespace HJ54
{
/// <summary>
/// 1.用两个栈分别压数字和运算符;
/// 2.如果当前运算符优先级('*/')高于栈顶运算符('+-')优先级,则将运算符入栈;
/// 3.反之,从数字栈中弹出两个数,从运算符栈中弹出栈顶运算符,进行运算,数字栈压入运算结果,符号栈压入当前运算符。
/// 4..出现左括号,则直接压入;出现右括号,则从数字栈中弹出两个数,从运算符栈中弹出栈顶运算符,进行运算,数字栈压入运算结果,重复该操作直到栈顶弹出左括号为止。
/// </summary>
internal class Program
{
static void Main(string[] args)
{
string str = Console.ReadLine();
str = str.Replace('{', '(').Replace('}', ')').Replace('[', '(').Replace(']', ')');
//外面加一层()不影响结果,方便后面计算能够遍历完整,同时能防止最后一个数字无法提取压入数据栈
str = $"({str})";
char[] chars = str.ToCharArray();
Stack<int> numbers = new Stack<int>();
StringBuilder sb = new StringBuilder();
Stack<char> ops = new Stack<char>();
for (int i = 0; i < chars.Length; i++)
{
char curChar = chars[i];
#region 这一段用于将数字提取出来
if (!char.IsDigit(curChar) && sb.Length > 0)
{
if (int.TryParse(sb.ToString(), out int num))
{
numbers.Push(num);
sb.Clear();
}
}
//判断是否为负号
if (curChar == '-')
{
//当i == 0时,-表示号
if (i == 0)
{
sb.Append(curChar);
continue;
}
char lastChar = chars[i - 1];
//当前面是+-*/(时,-表示号
if (lastChar == '+' || lastChar == '-' || lastChar == '*' || lastChar == '/' || lastChar == '(')
{
sb.Append(curChar);
}
}
if (char.IsDigit(curChar))
{
sb.Append(curChar);
continue;
}
#endregion
if (curChar == '(')
{
ops.Push(curChar);
continue;
}
if (curChar == '+' || curChar == '-' || curChar == '*' || curChar == '/')
{
while (true)
{
if (ops.Count == 0)
{
break;
}
char topOpt = ops.Peek();
//扫描到当前运算符时,如果当前运算符栈顶运算符可用运算,
//则进行运算,直到不满足运算条件为止
if (CanCal(topOpt, curChar))
{
char opt = ops.Pop();
int num02 = numbers.Pop();
int num01 = numbers.Pop();
numbers.Push(Cal(num01, num02, opt));
}
else
{
break;
}
}
ops.Push(curChar);
continue;
}
if (curChar == ')')
{
while (true)
{
if (ops.Count == 0)
{
break;
}
char opt = ops.Pop();
if (opt == '(')
{
break;
}
int num02 = numbers.Pop();
int num01 = numbers.Pop();
numbers.Push(Cal(num01, num02, opt));
}
}
}
Console.WriteLine(numbers.Peek());
}
/// <summary>
/// 判断扫描到当前运算符时,运算符栈顶运算符是否可用于计算运算
/// </summary>
static bool CanCal(char topChar, char curChar)
{
//如果当前运算符栈顶符是左括号时,不可运算,因为括号是不能进行运算的
if (topChar == '(')
{
return false;
}
//如果当前运算符栈顶符是*或者/,可运算,因为A*B或者A/B状态可直接进行运算,
if (topChar == '*' || topChar == '/')
{
return true;
}
//如果当前运算符栈顶符是+或者-,并且当前扫描到运算符也是+或者-,可运算,
return curChar == '+' || curChar == '-';
}
static int Cal(int num01, int num02, char opt)
{
switch (opt)
{
case '+':
return num01 + num02;
case '-':
return num01 - num02;
case '*':
return num01 * num02;
case '/':
return num01 / num02;
default:
return 0;
}
}
}
}