string類型的公式如何用程序計算 括號處理算法方案 如計算 sin(3*π-2cos(3*π-2))*2-sin(0.12*π)

        /// <summary>
        /// 根據算術公式進行計算
        /// </summary>
        /// <param name="formula">string 類型的公式 如:sin(3*π-2cos(3*π-2))*2-sin(0.12*π) </param>
        /// <returns></returns>
        public static double formulaComput(string formula)
        {
            //先把常量變成數字
            formula = formula.Replace("π", Math.PI.ToString());
            formula = formula.Replace('(', '(').Replace(')', ')');

            //預處理獲取括號所在的index
            List<ComputEntity> computEntities = new List<ComputEntity>();
            List<string> rexs = new List<string> { "sin", "cos", "sinh", "cosh" };
            foreach (var rex in rexs)
            {
                var matches = Regex.Matches(formula, rex + @"\(");
                foreach (Match match in matches)
                {
                    ComputEntity computEntity = new ComputEntity();
                    computEntity.beginBracketsIndex = match.Index + match.Length;
                    computEntity.beginIndex = match.Index;
                    computEntity.rex = rex;
                    computEntity.matchLength = match.Length;
                    computEntities.Add(computEntity);
                }
            }

            //根據括號的所在處理sin ,cos 等函數,一定要先處理最後的那個,因爲,這個很難解釋
            //仔細想想就知道了,就是這個理,從公式的最後處理到前面是正確的做法
            foreach (var comput in computEntities.OrderByDescending(t => t.beginIndex))
            {
                string tempFormula = formula.Substring(comput.beginBracketsIndex, formula.Length - comput.beginBracketsIndex);
                int leftBracketsCount = 0;
                for (int i = 0; i < tempFormula.Length; i++)
                {
                    if (tempFormula[i].Equals(')'))
                    {
                        if (leftBracketsCount == 0)
                        {
                            comput.lastIndex = comput.beginBracketsIndex + i;
                            comput.contentLengh = i;
                            comput.allLength = comput.matchLength + i + 1;
                            break;
                        }
                        else
                        {
                            leftBracketsCount--;
                        }
                    }
                    else if (tempFormula[i].Equals('('))
                    {
                        leftBracketsCount++;
                    }
                }

                var result = tableComput(formula.Substring(comput.beginBracketsIndex, comput.contentLengh));



                //根據要計算的方法,進行計算
                switch (comput.rex)
                {
                    case "sin":
                        result = Math.Sin(result);
                        formula = formula.Replace(formula.Substring(comput.beginIndex, comput.allLength), result.ToString());
                        break;
                    case "cos":
                        result = Math.Cos(result);
                        formula = formula.Replace(formula.Substring(comput.beginIndex, comput.allLength), result.ToString());
                        break;
                    case "sinh":
                        result = Math.Sinh(result);
                        formula = formula.Replace(formula.Substring(comput.beginIndex, comput.allLength), result.ToString());
                        break;
                    case "cosh":
                        result = Math.Cosh(result);
                        formula = formula.Replace(formula.Substring(comput.beginIndex, comput.allLength), result.ToString());
                        break;
                    default:
                        break;
                }

            }

            return tableComput(formula);

        }



        /// <summary>
        /// 用table 這個庫來進行計算
        /// </summary>
        /// <param name="formula"></param>
        /// <returns></returns>
        public static double tableComput(string formula)
        {
            DataTable dataTable = new DataTable();
            Console.WriteLine(formula);
            var result = dataTable.Compute(formula, "");
            return Convert.ToDouble(result);
        }
 /// <summary>
    /// 計算公式實體
    /// </summary>
    public class ComputEntity
    {
        public string rex;

        public int matchLength;

        public int beginIndex;

        public int beginBracketsIndex;

        public int lastIndex;

        public int contentLengh;

        public int allLength;
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章