JudgeHelper.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Text;
  5. namespace Core.StlMes.Client.Judge.Commons
  6. {
  7. public static class JudgeHelper
  8. {
  9. private static Microsoft.JScript.Vsa.VsaEngine ve = Microsoft.JScript.Vsa.VsaEngine.CreateEngine();
  10. /// <summary>
  11. /// 计算字符串表达式 如:(2*a-8)/d 或者三元运算 (2*a-8)/d > 0 ? 2*a : (2*a + 1)
  12. /// </summary>
  13. /// <param name="formula">输入的表现公式</param>
  14. /// <returns></returns>
  15. public static string Eval(string express)
  16. {
  17. //1942.57*(Axc^0.2)/(517^0.9) 8^2^4
  18. express = powSign(express);
  19. express = tanh(express);
  20. //1942.57*(Math.Pow((double)1, (double)0.2))/(Math.Pow((double)517, (double)0.9))
  21. string result = "";
  22. try
  23. {
  24. result = Microsoft.JScript.Eval.JScriptEvaluate(express, ve).ToString();
  25. }
  26. catch (Exception ex)
  27. {
  28. Debug.WriteLine(ex.Message);
  29. return express;
  30. }
  31. return result;
  32. }
  33. /**
  34. * 双曲正切函数计算
  35. * @param express
  36. * @return
  37. */
  38. private static string tanh(string express)
  39. {
  40. if (!express.Contains("tanh"))
  41. {
  42. return express;
  43. }
  44. //2*tan((1+1))
  45. char[] exChars = express.ToCharArray();
  46. int tanhIndex = express.IndexOf("tanh(");
  47. if (express.Length <= tanhIndex + 4) return express;
  48. int leftParenthesesCount = 0;//左括号数
  49. int rightParenthesesIndex = 0;
  50. for (int i = tanhIndex + 4; i < express.Length; i++)
  51. {
  52. if (exChars[i] == '(')
  53. {
  54. leftParenthesesCount++;
  55. continue;
  56. }
  57. if (exChars[i] == ')')
  58. {
  59. if (leftParenthesesCount == 0)
  60. {
  61. rightParenthesesIndex = i;
  62. }
  63. else
  64. {
  65. leftParenthesesCount--;
  66. }
  67. }
  68. }
  69. string subExpress = express.Substring(tanhIndex + 4, rightParenthesesIndex - 1 - (tanhIndex + 4) + 1);
  70. if (subExpress.Contains("tanh"))
  71. {
  72. subExpress = tanh(subExpress);
  73. }
  74. string strSubResult = Eval(subExpress);
  75. if (strSubResult.TryParseDouble())
  76. {
  77. Double DSubResult = Math.Tanh(double.Parse(strSubResult));
  78. string replaceStr = express.Substring(tanhIndex, rightParenthesesIndex - tanhIndex);
  79. express = express.Replace(replaceStr, DSubResult.ToString());
  80. }
  81. return express;
  82. }
  83. private static string powSign(string express)
  84. {
  85. if (!express.Contains("^")) return express;
  86. //2+(6+2)^2+2^2
  87. String sings = "+-*/()^";
  88. int index = express.IndexOf("^");
  89. char[] strChars = express.Substring(0, index).ToCharArray();
  90. char[] str2Chars = express.Substring(index + 1).ToCharArray();
  91. StringBuilder strBld = new StringBuilder();
  92. strBld.Append(strChars);
  93. int khCnt = 0;
  94. bool isKh = false;
  95. for (int i = strChars.Length - 1; i >= 0; i--)
  96. {
  97. char strChar = strChars[i];
  98. if (strChar == ')')
  99. {
  100. if (i == strChars.Length - 1)
  101. {
  102. isKh = true;
  103. }
  104. khCnt++;
  105. }
  106. else if (strChar == '(')
  107. {
  108. khCnt--;
  109. }
  110. if (isKh)
  111. {
  112. if (khCnt == 0)
  113. {
  114. strBld.Insert(i, "Math.pow(");
  115. break;
  116. }
  117. }
  118. else
  119. {
  120. if (i == 0)
  121. {
  122. strBld.Insert(i, "Math.pow(");
  123. break;
  124. }
  125. else if (sings.IndexOf(strChar) > -1)
  126. {
  127. strBld.Insert(i + 1, "Math.pow(");
  128. break;
  129. }
  130. }
  131. }
  132. //2+(6+2)^2+2^2
  133. StringBuilder str2Bld = new StringBuilder();
  134. str2Bld.Append(str2Chars);
  135. khCnt = 0;
  136. isKh = false;
  137. for (int i = 0; i < str2Chars.Length; i++)
  138. {
  139. char strChar = str2Chars[i];
  140. if (i == 0)
  141. {
  142. str2Bld.Insert(0, ", ");
  143. if (strChar == '(')
  144. {
  145. isKh = true;
  146. }
  147. }
  148. if (strChar == '(')
  149. {
  150. khCnt++;
  151. }
  152. else if (strChar == ')')
  153. {
  154. khCnt--;
  155. }
  156. if (isKh)
  157. {
  158. if (khCnt == 0)
  159. {
  160. str2Bld.Insert(i + 3, ")");
  161. break;
  162. }
  163. }
  164. else
  165. {
  166. if (i == str2Chars.Length - 1)
  167. {
  168. str2Bld.Insert(i + 3, ")");
  169. break;
  170. }
  171. else if (sings.IndexOf(strChar) > -1)
  172. {
  173. str2Bld.Insert(i + 2, ")");
  174. break;
  175. }
  176. }
  177. }
  178. express = strBld.ToString() + str2Bld.ToString();
  179. return powSign(express);
  180. }
  181. public static string GetExpress(string stdMinSign, string stdMin, string stdMaxSign, string stdMax)
  182. {
  183. List<string> expressList = new List<string>();
  184. if (stdMin != "")
  185. {
  186. expressList.Add(stdMinSign + stdMin);
  187. }
  188. if (stdMax != "")
  189. {
  190. expressList.Add(stdMaxSign + stdMax);
  191. }
  192. return string.Join(";", expressList);
  193. }
  194. public static bool JudgeExpress(string value, string express)
  195. {
  196. if (express == "") return true;
  197. if (value == "" && express != "") return false;
  198. if (value == "" && express == "") return true;
  199. string[] expressAry = express.Split(';');
  200. double outValue;
  201. bool outBool;
  202. bool outBool2;
  203. if (expressAry.Length == 1)
  204. {
  205. if (expressAry[0].StartsWith("="))
  206. {
  207. if (!double.TryParse(expressAry[0].TrimStart('='), out outValue))
  208. {
  209. return false;
  210. }
  211. expressAry[0] = expressAry[0].Replace("=", "==");
  212. }
  213. string evalResult = (value + expressAry[0]).Eval();
  214. if (bool.TryParse(evalResult, out outBool))
  215. {
  216. return outBool;
  217. }
  218. else
  219. {
  220. return false;
  221. }
  222. }
  223. else
  224. {
  225. if (expressAry[0].StartsWith("="))
  226. {
  227. if (!double.TryParse(expressAry[0].TrimStart('='), out outValue))
  228. {
  229. return false;
  230. }
  231. expressAry[0] = expressAry[0].Replace("=", "==");
  232. }
  233. if (expressAry[1].StartsWith("="))
  234. {
  235. if (!double.TryParse(expressAry[1].TrimStart('='), out outValue))
  236. {
  237. return false;
  238. }
  239. expressAry[1] = expressAry[0].Replace("=", "==");
  240. }
  241. if (!bool.TryParse((value + expressAry[0]).Eval(), out outBool))
  242. {
  243. return false;
  244. }
  245. if (!bool.TryParse((value + expressAry[1]).Eval(), out outBool2))
  246. {
  247. return false;
  248. }
  249. return outBool & outBool2;
  250. }
  251. }
  252. public static string GetRoundValue(string value, int round)
  253. {
  254. value = Eval(value);
  255. if (value.TryParseDecimal())
  256. {
  257. value = Math.Round(decimal.Parse(value), round).ToString();
  258. }
  259. return value;
  260. }
  261. //public static bool CompareExpress(string value, string express)
  262. //{
  263. // //string[] expressArray = express.TrimStart('<', '>', '=');// Split(new string[] { "=", "<", ">", "<=", ">=" },
  264. // // StringSplitOptions.RemoveEmptyEntries);
  265. // //if (expressArray.Length != 2) return false;
  266. // if (value == "") return false;
  267. // string express1 = value;
  268. // string symbol = "";
  269. // if (express.StartsWith("<="))
  270. // {
  271. // symbol = "<=";
  272. // }
  273. // else if (express.StartsWith(">="))
  274. // {
  275. // symbol = ">=";
  276. // }
  277. // else if (express.StartsWith("="))
  278. // {
  279. // symbol = "=";
  280. // }
  281. // else if (express.StartsWith("<"))
  282. // {
  283. // symbol = "<";
  284. // }
  285. // else if (express.StartsWith(">"))
  286. // {
  287. // symbol = ">";
  288. // }
  289. // else
  290. // {
  291. // return false;
  292. // }
  293. // string express2 = express.TrimStart('<', '>', '=');
  294. // decimal? dcmExp1 = 0;
  295. // decimal? dcmExp2 = 0;
  296. // if (!express1.TryParseDecimal())
  297. // {
  298. // express1 = express1.Replace("C", "1");
  299. // dcmExp1 = express1.CompileFormula();
  300. // }
  301. // else
  302. // {
  303. // dcmExp1 = decimal.Parse(express1);
  304. // }
  305. // if (!express2.TryParseDecimal())
  306. // {
  307. // express2 = express2.Replace("C", "1");
  308. // dcmExp2 = express2.CompileFormula();
  309. // }
  310. // else
  311. // {
  312. // dcmExp2 = decimal.Parse(express2);
  313. // }
  314. // if (symbol == "<=")
  315. // {
  316. // return dcmExp1 <= dcmExp2;
  317. // }
  318. // else if (symbol == ">=")
  319. // {
  320. // return dcmExp1 >= dcmExp2;
  321. // }
  322. // else if (symbol == "=")
  323. // {
  324. // return dcmExp1 == dcmExp2;
  325. // }
  326. // else if (symbol == "<")
  327. // {
  328. // return dcmExp1 < dcmExp2;
  329. // }
  330. // else if (symbol == ">")
  331. // {
  332. // return dcmExp1 > dcmExp2;
  333. // }
  334. // else
  335. // {
  336. // return false;
  337. // }
  338. //}
  339. }
  340. }