using System;
using System.Collections;

namespace UUN
{
    /// <summary>
    /// 将字符串数学表达式计算出结果
    /// </summary>
    public static class 字符串计算
    {
        //中序转换成后序表达式再计算
        // 如：23+56/(102-100)*((36-24)/(8-6))
        // 转换成：23|56|102|100|-|/|*|36|24|-|8|6|-|/|*|+"
        //以便利用栈的方式都进行计算。
        public static string 计算结果(string 表达式)
        {
            ArrayList 计算列表 = new ArrayList();
            string 计算1;
            string 表达式字符串 = "";
            string 计算2;
            表达式 = 表达式.Replace(" ", "");
            while (表达式.Length > 0)
            {
                计算2 = "";
                //取数字处理
                if (Char.IsNumber(表达式[0]))
                {
                    while (Char.IsNumber(表达式[0]))
                    {
                        计算2 += 表达式[0].ToString();
                        表达式 = 表达式.Substring(1);
                        if (表达式 == "") break;


                    }
                    表达式字符串 += 计算2 + "|";
                }

                //取“C”处理
                if (表达式.Length > 0 && 表达式[0].ToString() == "(")
                {
                    计算列表.Add("(");
                    表达式 = 表达式.Substring(1);
                }

                //取“)”处理
                计算2 = "";
                if (表达式.Length > 0 && 表达式[0].ToString() == ")")
                {
                    do
                    {

                        if (计算列表[计算列表.Count - 1].ToString() != "(")
                        {
                            计算2 += 计算列表[计算列表.Count - 1].ToString() + "|";
                            计算列表.RemoveAt(计算列表.Count - 1);
                        }
                        else
                        {
                            计算列表.RemoveAt(计算列表.Count - 1);
                            break;
                        }

                    } while (true);
                    表达式字符串 += 计算2;
                    表达式 = 表达式.Substring(1);
                }

                //取运算符号处理
                计算2 = "";
                if (表达式.Length > 0 && (表达式[0].ToString() == "*" || 表达式[0].ToString() == "/" || 表达式[0].ToString() == "+" || 表达式[0].ToString() == "-"))
                {
                    计算1 = 表达式[0].ToString();
                    if (计算列表.Count > 0)
                    {

                        if (计算列表[计算列表.Count - 1].ToString() == "(" || 判断优先级(计算1, 计算列表[计算列表.Count - 1].ToString()))
                        {
                            计算列表.Add(计算1);
                        }
                        else
                        {
                            计算2 += 计算列表[计算列表.Count - 1].ToString() + "|";
                            计算列表.RemoveAt(计算列表.Count - 1);
                            计算列表.Add(计算1);
                            表达式字符串 += 计算2;

                        }

                    }
                    else
                    {
                        计算列表.Add(计算1);
                    }
                    表达式 = 表达式.Substring(1);
                }
            }

            计算2 = "";
            while (计算列表.Count != 0)
            {
                计算2 += 计算列表[计算列表.Count - 1].ToString() + "|";
                计算列表.RemoveAt(计算列表.Count - 1);
            }

            表达式字符串 += 计算2.Substring(0, 计算2.Length - 1); ;


            return 计算结果_(表达式字符串);

        }


        // 第二步:把转换成后序表达的式子计算
        //23|56|102|100|-|/|*|36|24|-|8|6|-|/|*|+"
        private static string 计算结果_(string 表达式)
        {
            //定义两个栈
            ArrayList 计算列表 = new ArrayList();
            float 计算1;
            float 计算2;
            string[] 计算3;

            表达式 = 表达式.Replace(" ", "");
            计算3 = 表达式.Split(Convert.ToChar("|"));

            for (int i = 0; i < 计算3.Length; i++)
            {
                if (Char.IsNumber(计算3[i], 0))
                {
                    计算列表.Add(计算3[i].ToString());
                }
                else
                {
                    //两个操作数退栈和一个操作符退栈计算
                    计算2 = (float)Convert.ToDouble(计算列表[计算列表.Count - 1]);
                    计算列表.RemoveAt(计算列表.Count - 1);
                    计算1 = (float)Convert.ToDouble(计算列表[计算列表.Count - 1]);
                    计算列表.RemoveAt(计算列表.Count - 1);
                    计算列表.Add(计算(计算1, 计算2, 计算3[i]).ToString());
                }

            }


            return 计算列表[0].ToString();
        }



        //判断两个运算符优先级别
        private static bool 判断优先级(string 运算符1, string 运算符2)
        {

            if (运算符1 == "*" && 运算符2 == "+")
                return true;
            else if (运算符1 == "*" && 运算符2 == "-")
                return true;
            else if (运算符1 == "/" && 运算符2 == "+")
                return true;
            else if (运算符1 == "/" && 运算符2 == "-")
                return true;
            else
                return false;
        }

        //计算
        private static float 计算(float 值1, float 值2, string 运算符)
        {
            switch (运算符)
            {
                case "*":
                    值1 *= 值2;
                    break;
                case "/":
                    值1 /= 值2;
                    break;
                case "+":
                    值1 += 值2;
                    break;
                case "-":
                    值1 -= 值2;
                    break;
                default:
                    break;
            }
            return 值1;
        }
    }
}