namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {      
            string str = "13+1*(15-3)+8/4";
            double r=Calculate(str);
            Console.Write(r);
        }
        public static double Calculate(string s)
        {
            int index = 0;
            MyStack<double> stNum = new MyStack<double>();//数栈
            MyStack<Node> stOp = new MyStack<Node>();//符号栈
            char[] c = new char[100];
            c = s.ToCharArray();//将字符串转换成字符数组
            while (index < c.Length)
            {
                if (c[index] > '0' && c[index] < '9')//判断是否为数字
                {
                    int testIndex = index;//定义一个临时索引
                    index = index+1;
                    while (index < c.Length && c[index] > '0' && c[index] < '9' || c[index] == '.')//如果是数字或. 索引向后移
                    {
                        index++;
                    }
                    double d = Convert.ToDouble(s.Substring(testIndex, index - testIndex));//截取
                    stNum.Push(d);//将数字压到数字栈中
                    continue;
                }
                if (c[index] == '+' || c[index] == '-')  
                {
                    Node opNode = new Node(c[index], 1);//优先级为1
                    if (stOp.isEmpty())
                    {
                        stOp.Push(opNode);//将符号放入符号栈中
                    }
                    else
                    {
                        Node op1 = stOp.top();//
                        if (opNode.level > op1.level)
                        {
                            stOp.Push(opNode);
                        }
                        else
                        {
                            Node op2 = stOp.Pop();//从符号栈取出一个
                            double Num2 = stNum.Pop();//从数字栈取出两个,先取出的放后边
                            double Num1 = stNum.Pop();
                            double r = CalNums(Num1, Num2, op2);//计算结果给d
                            stNum.Push(r);// 压入栈
                            if (stOp.isEmpty())
                            {
                                stOp.Push(opNode);
                            }
                            else
                            {
                                op1 = stOp.top();
                            }
                        }
                    }
                    index++;
                    continue;
                }
                if (c[index] == '*' || c[index] == '/' || c[index] == '%')
                {
                    Node opNode = new Node(c[index], 2);
                    if (stOp.isEmpty())
                    {
                        stOp.Push(opNode);
                    }
                    else
                    {
                        Node op1 = stOp.top();
                        if (opNode.level == op1.level)
                        {
                            Node op2 = stOp.Pop();
                            double Num2 = stNum.Pop();
                            double Num1 = stNum.Pop();
                            double r = CalNums(Num1, Num2, op2);
                            stNum.Push(r);
                            if (stOp.isEmpty())
                            {
                                stOp.Push(opNode);
                            }
                            else
                            {
                                op1 = stOp.top();
                            }
                        }
                    }
                    index++;
                    continue;
                }
                if (c[index] == '(')
                {
                    Node opNode = new Node(c[index], -1);
                    stOp.Push(opNode);
                    index++;
                    continue;
                }
                if (c[index] == ')')
                {
                    while (!stOp.isEmpty() && stOp.top().op != '(')
                    {
                        Node op1 = stOp.top();
                        Node op2 = stOp.Pop();
                        double Num2 = stNum.Pop();
                        double Num1 = stNum.Pop();
                        double r = CalNums(Num1, Num2, op2);
                        stNum.Push(r);
                    }
                    stOp.Pop();
                    index++;
                    continue;
                }
            }
            while (!stOp.isEmpty()) //如果遍历结束,栈中还有数据
            {
                Node op1 = stOp.top();
                Node op2 = stOp.Pop();
                double Num2 = stNum.Pop();
                double Num1 = stNum.Pop();
                double r = CalNums(Num1, Num2, op2);
                stNum.Push(r);
            }
            return stNum.Pop();//返回最后一个数
        }
        private static double CalNums(double Num1, double Num2, Node Op)
        {
            double result = 0.00;
            switch (Op.op)
            {
                case '+':
                    result = Num1 + Num2;
                    break;
                case '-':
                    result = Num1 - Num2;
                    break;
                case '*':
                    result = Num1 * Num2;
                    break;
                case '/':
                    result = Num1 / Num2;
                    break;
                case '%':
                    result = Num1 % Num2;
                    break;
            }
            return result;
        }
    }
    public class MyStack<T>
    {
        private int Top = 0;
        List<T> list = new List<T>();
        public MyStack()
        {
            list = new List<T>();
            Top = -1;
        }
        public int Count
        {
            get { return Count; }
        }
        public T Pop() //出栈
        {
            Top--;
            T s = list[Top];
            list.RemoveAt(Top);
            return s;
        }
        public void Push(T s)//入栈
        {
            list.Add(s);
            Top++;
        }
        public void clear()//清空栈
        {
            list.Clear();
            Top = -1;
        }
        public object peek()//查看栈顶的数据项
        {
            return list[Top];
        }
        public T top()
        {
            return list[Top - 1];
        }
        public Boolean isEmpty()//判断是否为空
        {
            if (list.Count == 0)
                return true;
            else
                return false;
        }
    }
    public class Node
    {
        public char op;
        public int level;
        public Node(char op, int level)
        {
            // TODO: Complete member initialization
            this.op = op;
            this.level = level;
        }
    }
}