110,571
社区成员
发帖
与我相关
我的任务
分享
static void Main(string[] args)
{
DataTable table = new DataTable();
table.Columns.Add("a");
table.Columns.Add("ab");
table.Columns.Add("c");
table.Columns.Add("cd");
table.Columns.Add("e");
table.Rows.Add(1, 23, 4, 5, "a-ab+c-cd");
table.Rows.Add(3,2,5,8,"ab+c");
table.Rows.Add(5, 55, 9, 99, "ab/a*(cd-c)");
table.Rows.Cast<DataRow>().ToList().ForEach(row => Console.WriteLine(Compute(row, row["e"].ToString())));
Console.ReadLine();
}
static int Compute(DataRow row, string formula)
{
foreach(Match field in Regex.Matches(row["e"].ToString(), @"\w+").Cast<Match>().OrderBy(m => -m.Value.Length))
{
formula = formula.Replace(field.Value, row[field.Value].ToString());
}
return Convert.ToInt32( row.Table.Compute(formula, ""));
}
private int OperateCount(string opStr)
{
Dictionary<string, int> xDic = new Dictionary<string, int>();
xDic.Add("+", 0);
xDic.Add("*", 1);
List<int> numList = new List<int>();
List<string> OperList = new List<string>();
for (var i = 0; i < opStr.Length; i++)
{
var thisChar = opStr[i].ToString();
//如果是数字,直接入栈
if (isNum(thisChar))
{
//如果是数字,直接入栈
numList.Add(int.Parse(thisChar));
}
else
{
//如果是运算符,则与最后一个运算符比较优先级
if (OperList.Count == 0 || xDic[thisChar] > xDic[OperList.Last()])
{
//如果是第一个运算符或优先级大于上一个运算符则入栈
OperList.Add(thisChar);
}
else if (xDic[thisChar] <= xDic[OperList.Last()])
{
//这个判断条件只适用于只有加法乘法的简单运算公式
Operate(numList, OperList);
OperList.Add(thisChar);
}
}
}
while (numList.Count > 1)
{
Operate(numList, OperList);
}
return numList[0];
}
private void Operate(List<int> numList, List<string> OperList)
{
//ListPop模拟pop操作
int param1 = ListPop(numList);
int param2 = ListPop(numList);
string opChar = ListPop(OperList);
switch (opChar)
{
case "+":
numList.Add(param1 + param2);
break;
case "*":
numList.Add(param1 * param2);
break;
}
}
[/quote]
简单实现了下加法和乘法的,原理基本是一样的,就是操作数据栈和操作符栈,更多的运算符优先级二维表lz可以在网上搜索。private int OperateCount(string opStr)
{
Dictionary<string, int> xDic = new Dictionary<string, int>();
xDic.Add("+", 0);
xDic.Add("*", 1);
List<int> numList = new List<int>();
List<string> OperList = new List<string>();
for (var i = 0; i < opStr.Length; i++)
{
var thisChar = opStr[i].ToString();
//如果是数字,直接入栈
if (isNum(thisChar))
{
//如果是数字,直接入栈
numList.Add(int.Parse(thisChar));
}
else
{
//如果是运算符,则与最后一个运算符比较优先级
if (OperList.Count == 0 || xDic[thisChar] > xDic[OperList.Last()])
{
//如果是第一个运算符或优先级大于上一个运算符则入栈
OperList.Add(thisChar);
}
else if (xDic[thisChar] <= xDic[OperList.Last()])
{
//这个判断条件只适用于只有加法乘法的简单运算公式
Operate(numList, OperList);
OperList.Add(thisChar);
}
}
}
while (numList.Count > 1)
{
Operate(numList, OperList);
}
return numList[0];
}
private void Operate(List<int> numList, List<string> OperList)
{
//ListPop模拟pop操作
int param1 = ListPop(numList);
int param2 = ListPop(numList);
string opChar = ListPop(OperList);
switch (opChar)
{
case "+":
numList.Add(param1 + param2);
break;
case "*":
numList.Add(param1 * param2);
break;
}
}
static void Main(string[] args)
{
var s = "(double a,b,c) => a+b*c";
var a = 100;
var b = 3.44;
var c = 2330;
var r = new ExprParser().Parse(s);
Console.WriteLine(r.Compile().DynamicInvoke(a, b, c)); //8115.2
}
/// <summary>
/// ExprParser has 3 naming scope
/// Global : available for all Parser instance.
/// Parser : available for current Parser instance.
/// Inline : available for current expression.
///
/// User can create multiple parser instance for different naming scope
/// One parser can create multiple expression with the same naming scope
/// One expression can define in-line namespace and parameter only for current expression scope
/// </summary>
public class ExprParser
{
#region namespace, parameter and type: case sensitive
internal static Dictionary<string, Type> SystemType = SetSystemType();
private static Dictionary<string, Type> SetSystemType()
{
// system value types : http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx
Dictionary<string, Type> dic = new Dictionary<string, Type>();
dic.Add("bool", typeof(bool));
dic.Add("char", typeof(char));
dic.Add("string", typeof(string));
dic.Add("byte", typeof(byte));
dic.Add("sbyte", typeof(sbyte));
dic.Add("short", typeof(short));
dic.Add("ushort", typeof(ushort));
dic.Add("int", typeof(int));
dic.Add("uint", typeof(uint));
dic.Add("long", typeof(long));
dic.Add("ulong", typeof(ulong));
dic.Add("float", typeof(float));
dic.Add("double", typeof(double));
dic.Add("decimal", typeof(decimal));
dic.Add("enum", typeof(Enum));
dic.Add("object", typeof(object));
return dic;
}
internal static Dictionary<Type, Type> NullableType = SetNullableType();
private static Dictionary<Type, Type> SetNullableType()
{
Dictionary<Type, Type> dic = new Dictionary<Type, Type>();
dic.Add(typeof(bool), typeof(bool?));
dic.Add(typeof(char), typeof(char?));
dic.Add(typeof(byte), typeof(byte?));
dic.Add(typeof(sbyte), typeof(sbyte?));
dic.Add(typeof(short), typeof(short?));
dic.Add(typeof(ushort), typeof(ushort?));
dic.Add(typeof(int), typeof(int?));
dic.Add(typeof(uint), typeof(uint?));
dic.Add(typeof(long), typeof(long?));
dic.Add(typeof(ulong), typeof(ulong?));
dic.Add(typeof(float), typeof(float?));
dic.Add(typeof(double), typeof(double?));
dic.Add(typeof(decimal), typeof(decimal?));
return dic;
}
// namespace for static data type
public static Using Using = new Using();
internal Assembly caller_assembly = null;
// parameter type
public static Dictionary<string, Type> GlobalParameterType = new Dictionary<string, Type>(); // Global scope
public Dictionary<string, Type> ParameterType = new Dictionary<string, Type>(); // Parser scope
private Dictionary<string, Type> inlineParameterType = null; // Expr scope
// parameter value
public static Dictionary<string, object> GlobalParameterValue = new Dictionary<string, object>(); // Global scope
public Dictionary<string, object> ParameterValue = new Dictionary<string, object>(); // Parser scope
/// <summary>
/// check by order:
/// - System Type // user type cannot be the same with system type. check system type first is for performance
/// - Type.GetType(type_name)
/// - Type from Local Namespace
/// - Type from Globel Namespace
/// limitation:
/// Type.GetType use AssmblyQulifiedName: "ns.type, ns". not include version info, "type" part not include "."
/// </summary>
/// <param name="name">type or instance object name</param>
/// <returns></returns>
internal Type QueryStaticType(string type_name)
{
// check with dicSystemType
if (SystemType.ContainsKey(type_name))
return SystemType[type_name];
// check type_name itself
Type t = null;
if ((t = Type.GetType(type_name)) != null) return t; // check System(mscorlib) assembly
if (caller_assembly != null && (t = caller_assembly.GetType(type_name)) != null) return t; // check caller assembly
foreach (string ns in Using.namespace_list.Keys)
{
string full_type_name = ns + "." + type_name;
if (Using.namespace_list[ns] == null)
{
if ((t = Type.GetType(full_type_name)) != null) return t; // check System(mscorlib) assembly
if (caller_assembly != null && (t = caller_assembly.GetType(full_type_name)) != null) return t; // check caller assembly
if ((t = Type.GetType(full_type_name + ", " + ns)) != null) return t; // check namespace as assembly name
}
else if (Using.namespace_list[ns] != null && (t = Using.namespace_list[ns].GetType(full_type_name)) != null) return t;
}
if (type_name.Contains(".") && (t = Type.GetType(type_name + ", " + type_name.Substring(0, type_name.LastIndexOf('.')))) != null)
return t;
//// check with Namespace
//if (this.Namespace != null)
//{
// foreach (string ns in this.Namespace)
// if ((t = Type.GetType(ns + "." + type_name)) != null
// || (t = Type.GetType(ns + "." + type_name + ", " + ns)) != null) return t;
//}
//// check with GlobalNamespace
//if (GlobalNamespace != null)
//{
// foreach (string ns in GlobalNamespace)
// if ((t = Type.GetType(ns + "." + type_name)) != null
// || (t = Type.GetType(ns + "." + type_name + ", " + ns)) != null) return t;
//}
//// check with localNamespace
//if (inlineNamespace != null)
//{
// foreach (string ns in inlineNamespace)
// if ((t = Type.GetType(ns + "." + type_name)) != null
// || (t = Type.GetType(ns + "." + type_name + ", " + ns)) != null) return t;
//}
return null;
}
/// <summary>
/// check by order
/// Parameter Type
/// Globel Parameter Type
/// queryParameterValue(parameter_name)
/// </summary>
/// <param name="parameter_name"></param>
/// <returns></returns>
internal Type QueryParameterType(string parameter_name)
{
if (ParameterType != null && ParameterType.ContainsKey(parameter_name))
return ParameterType[parameter_name];
else if (GlobalParameterType.ContainsKey(parameter_name))
return GlobalParameterType[parameter_name];
else if (inlineParameterType != null && inlineParameterType.ContainsKey(parameter_name))
return inlineParameterType[parameter_name];
return null;
}
// implicit conversion
internal static Dictionary<Type, List<Type>> dicImplicitConversion = SetImplicitConversionMap();
internal static Dictionary<Type, List<Type>> SetImplicitConversionMap()
{
Dictionary<Type, List<Type>> dic = new Dictionary<Type, List<Type>>();
dic.Add(typeof(char), new List<Type>(new Type[] { typeof(char), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(decimal), typeof(char?), typeof(ushort?), typeof(int?), typeof(uint?), typeof(long?), typeof(ulong?), typeof(float?), typeof(double?), typeof(decimal?) }));
dic.Add(typeof(byte), new List<Type>(new Type[] { typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(decimal), typeof(byte?), typeof(short?), typeof(ushort?), typeof(int?), typeof(uint?), typeof(long?), typeof(ulong?), typeof(float?), typeof(double?), typeof(decimal?) }));
dic.Add(typeof(sbyte), new List<Type>(new Type[] { typeof(sbyte), typeof(short), typeof(int), typeof(long), typeof(float), typeof(double), typeof(decimal), typeof(sbyte?), typeof(short?), typeof(int?), typeof(long?), typeof(float?), typeof(double?), typeof(decimal?) }));
dic.Add(typeof(short), new List<Type>(new Type[] { typeof(short), typeof(int), typeof(long), typeof(float), typeof(double), typeof(decimal), typeof(short?), typeof(int?), typeof(long?), typeof(float?), typeof(double?), typeof(decimal?) }));
dic.Add(typeof(ushort), new List<Type>(new Type[] { typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(decimal), typeof(ushort?), typeof(int?), typeof(uint?), typeof(long?), typeof(ulong?), typeof(float?), typeof(double?), typeof(decimal?) }));
dic.Add(typeof(int), new List<Type>(new Type[] { typeof(int), typeof(long), typeof(float), typeof(double), typeof(decimal), typeof(int?), typeof(long?), typeof(float?), typeof(double?), typeof(decimal?) }));
dic.Add(typeof(uint), new List<Type>(new Type[] { typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(decimal), typeof(uint?), typeof(long?), typeof(ulong?), typeof(float?), typeof(double?), typeof(decimal?) }));
dic.Add(typeof(long), new List<Type>(new Type[] { typeof(long), typeof(float), typeof(double), typeof(decimal), typeof(long?), typeof(float?), typeof(double?), typeof(decimal?) }));
dic.Add(typeof(ulong), new List<Type>(new Type[] { typeof(ulong), typeof(float), typeof(
1+2*3
这不算什么,那么运算一下if(x1 > 1000)
{
return Math.Power(x2, 2) + x3;
}
else if(d1 > new Date(2018,9,29) && Math.abs(p1)>0.0001)
{
return x2+x3/p1;
}
试试看你怎么生成两个栈来计算呢?这显然就比两个栈需要更多。