using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; namespace Core.StlMes.Client.Judge.Commons { public static class JudgeHelper { private static Microsoft.JScript.Vsa.VsaEngine ve = Microsoft.JScript.Vsa.VsaEngine.CreateEngine(); /// /// 计算字符串表达式 如:(2*a-8)/d 或者三元运算 (2*a-8)/d > 0 ? 2*a : (2*a + 1) /// /// 输入的表现公式 /// public static string Eval(string express) { //1942.57*(Axc^0.2)/(517^0.9) 8^2^4 express = powSign(express); express = tanh(express); //1942.57*(Math.Pow((double)1, (double)0.2))/(Math.Pow((double)517, (double)0.9)) string result = ""; try { result = Microsoft.JScript.Eval.JScriptEvaluate(express, ve).ToString(); } catch (Exception ex) { Debug.WriteLine(ex.Message); return express; } return result; } /** * 双曲正切函数计算 * @param express * @return */ private static string tanh(string express) { if (!express.Contains("tanh")) { return express; } //2*tan((1+1)) char[] exChars = express.ToCharArray(); int tanhIndex = express.IndexOf("tanh("); if (express.Length <= tanhIndex + 4) return express; int leftParenthesesCount = 0;//左括号数 int rightParenthesesIndex = 0; for (int i = tanhIndex + 4; i < express.Length; i++) { if (exChars[i] == '(') { leftParenthesesCount++; continue; } if (exChars[i] == ')') { if (leftParenthesesCount == 0) { rightParenthesesIndex = i; } else { leftParenthesesCount--; } } } string subExpress = express.Substring(tanhIndex + 4, rightParenthesesIndex - 1 - (tanhIndex + 4) + 1); if (subExpress.Contains("tanh")) { subExpress = tanh(subExpress); } string strSubResult = Eval(subExpress); if (strSubResult.TryParseDouble()) { Double DSubResult = Math.Tanh(double.Parse(strSubResult)); string replaceStr = express.Substring(tanhIndex, rightParenthesesIndex - tanhIndex); express = express.Replace(replaceStr, DSubResult.ToString()); } return express; } private static string powSign(string express) { if (!express.Contains("^")) return express; //2+(6+2)^2+2^2 String sings = "+-*/()^"; int index = express.IndexOf("^"); char[] strChars = express.Substring(0, index).ToCharArray(); char[] str2Chars = express.Substring(index + 1).ToCharArray(); StringBuilder strBld = new StringBuilder(); strBld.Append(strChars); int khCnt = 0; bool isKh = false; for (int i = strChars.Length - 1; i >= 0; i--) { char strChar = strChars[i]; if (strChar == ')') { if (i == strChars.Length - 1) { isKh = true; } khCnt++; } else if (strChar == '(') { khCnt--; } if (isKh) { if (khCnt == 0) { strBld.Insert(i, "Math.pow("); break; } } else { if (i == 0) { strBld.Insert(i, "Math.pow("); break; } else if (sings.IndexOf(strChar) > -1) { strBld.Insert(i + 1, "Math.pow("); break; } } } //2+(6+2)^2+2^2 StringBuilder str2Bld = new StringBuilder(); str2Bld.Append(str2Chars); khCnt = 0; isKh = false; for (int i = 0; i < str2Chars.Length; i++) { char strChar = str2Chars[i]; if (i == 0) { str2Bld.Insert(0, ", "); if (strChar == '(') { isKh = true; } } if (strChar == '(') { khCnt++; } else if (strChar == ')') { khCnt--; } if (isKh) { if (khCnt == 0) { str2Bld.Insert(i + 3, ")"); break; } } else { if (i == str2Chars.Length - 1) { str2Bld.Insert(i + 3, ")"); break; } else if (sings.IndexOf(strChar) > -1) { str2Bld.Insert(i + 2, ")"); break; } } } express = strBld.ToString() + str2Bld.ToString(); return powSign(express); } public static string GetExpress(string stdMinSign, string stdMin, string stdMaxSign, string stdMax) { List expressList = new List(); if (stdMin != "") { expressList.Add(stdMinSign + stdMin); } if (stdMax != "") { expressList.Add(stdMaxSign + stdMax); } return string.Join(";", expressList); } public static bool JudgeExpress(string value, string express) { if (express == "") return true; if (value == "" && express != "") return false; if (value == "" && express == "") return true; string[] expressAry = express.Split(';'); double outValue; bool outBool; bool outBool2; if (expressAry.Length == 1) { if (expressAry[0].StartsWith("=")) { if (!double.TryParse(expressAry[0].TrimStart('='), out outValue)) { return false; } expressAry[0] = expressAry[0].Replace("=", "=="); } string evalResult = (value + expressAry[0]).Eval(); if (bool.TryParse(evalResult, out outBool)) { return outBool; } else { return false; } } else { if (expressAry[0].StartsWith("=")) { if (!double.TryParse(expressAry[0].TrimStart('='), out outValue)) { return false; } expressAry[0] = expressAry[0].Replace("=", "=="); } if (expressAry[1].StartsWith("=")) { if (!double.TryParse(expressAry[1].TrimStart('='), out outValue)) { return false; } expressAry[1] = expressAry[0].Replace("=", "=="); } if (!bool.TryParse((value + expressAry[0]).Eval(), out outBool)) { return false; } if (!bool.TryParse((value + expressAry[1]).Eval(), out outBool2)) { return false; } return outBool & outBool2; } } public static string GetRoundValue(string value, int round) { value = Eval(value); if (value.TryParseDecimal()) { value = Math.Round(decimal.Parse(value), round).ToString(); } return value; } //public static bool CompareExpress(string value, string express) //{ // //string[] expressArray = express.TrimStart('<', '>', '=');// Split(new string[] { "=", "<", ">", "<=", ">=" }, // // StringSplitOptions.RemoveEmptyEntries); // //if (expressArray.Length != 2) return false; // if (value == "") return false; // string express1 = value; // string symbol = ""; // if (express.StartsWith("<=")) // { // symbol = "<="; // } // else if (express.StartsWith(">=")) // { // symbol = ">="; // } // else if (express.StartsWith("=")) // { // symbol = "="; // } // else if (express.StartsWith("<")) // { // symbol = "<"; // } // else if (express.StartsWith(">")) // { // symbol = ">"; // } // else // { // return false; // } // string express2 = express.TrimStart('<', '>', '='); // decimal? dcmExp1 = 0; // decimal? dcmExp2 = 0; // if (!express1.TryParseDecimal()) // { // express1 = express1.Replace("C", "1"); // dcmExp1 = express1.CompileFormula(); // } // else // { // dcmExp1 = decimal.Parse(express1); // } // if (!express2.TryParseDecimal()) // { // express2 = express2.Replace("C", "1"); // dcmExp2 = express2.CompileFormula(); // } // else // { // dcmExp2 = decimal.Parse(express2); // } // if (symbol == "<=") // { // return dcmExp1 <= dcmExp2; // } // else if (symbol == ">=") // { // return dcmExp1 >= dcmExp2; // } // else if (symbol == "=") // { // return dcmExp1 == dcmExp2; // } // else if (symbol == "<") // { // return dcmExp1 < dcmExp2; // } // else if (symbol == ">") // { // return dcmExp1 > dcmExp2; // } // else // { // return false; // } //} } }