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;
// }
//}
}
}