计算字符串得出结果
需求:
在C#中对⼀个字符串进⾏计算得出结果。
例如:“1+2+66+33”
字符串中的数字可以变化,累加(这⾥偷懒了限定成累加)的次数可以变化。
思路/解决⽅案:
1. ⽤JavaScript中的Eval把字符串转成对象进⾏计算
⽤Com控件计算⽅法,引⼊MSScriptControl.ScriptControlClass
2.⽤DataTable().Compute计算⽅法
3.把字符串表达式作为⼀个sql发到数据库计算后结果再回传到程序
4.分解字符串⽤ lambda表达式树动态创建⼀个(累加)表达式
说明:
我做了⼀个随机数,然后将每次随机出来的数字拼接成⼀个字符串展⽰出来。
再来解析这个字符串得出计算结果。
需要注意表达式树的⽅式,你的参数列表paramslist必须是  object[] 这个类型,我之前⽤的int[] 也可以编译但是在运⾏的时候会报错,你的paramenterArray应当就是构成binaryexpression的那些ParameterExpression。
如果你的业务⾥⾯要⽤到更加复杂运算,你需要亲⾃来尝试。
欢迎吐槽。
代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq.Expressions;
using System.Reflection;
namespace guess
{
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine(SetRandomVariable(GetTemplate()));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
#if DEBUG
Console.Read();
#endif
}
private static string GetTemplate()
{
StringBuilder stb = new StringBuilder();
stb.AppendLine("Global - OneERP {2}hr");
stb.AppendLine("FE - OneERP {3}hr");
stb.AppendLine("UK - OneERP {4}hr");
stb.AppendLine("Turkey - OneERP {5}hr");
stb.AppendLine("Vietnam – OneERP {6}hr");
stb.AppendLine("Singapore - OneERP {7}hr");
stb.AppendLine("CN - HZ {8}hr");
stb.AppendLine("Romania - OneERP {9}hr");
stb.AppendLine("Thailand - OneERP {10}hr");
stb.AppendLine("ZheJiang - OneERP {11}hr");
stb.AppendLine("Global - OneERP SSO {12}hr");
return stb.ToString();
}
private static string SetRandomVariable(string getTemplate)
{
int count = getTemplate.Split('\n').Length - 1;
Random randomVariable = new Random(DateTime.Now.Millisecond);
int max = 40;
StringBuilder formula = new StringBuilder();
object[] paramslist = new object[count];
for (int i = 0; i < paramslist.Length; i++)
{
if (i == paramslist.Length - 1)
{
paramslist[i] = max;
formula.Append(max);
}
else
{
paramslist[i] = available(ref max, ref formula);
}
}
/
/Com控件计算⽅法需要⽬标平台X86 D到引⽤的dll——属性——嵌⼊互操作类型——false
MSScriptControl.ScriptControl sc = new MSScriptControl.ScriptControlClass();
sc.Language = "JavaScript";
Console.WriteLine("{0}={1}", formula.ToString(), sc.Eval(formula.ToString()).ToString());
//DataTable().Compute计算⽅法
Console.WriteLine("{0}={1}", formula.ToString(), new System.Data.DataTable().Compute(formula.ToString(), "").ToString());
//另外有⼀种思路,把表达式作为⼀个sql发到数据库计算后结果再回传到程序。
//lambda表达式树动态创建⼀个累加的表达式需要 FrameWork 4.5
BinaryExpression binaryexpression = addExpression(count,null);
Console.WriteLine(binaryexpression);
LambdaExpression lambdaExpr = Expression.Lambda(binaryexpression, paramenterArray);
Delegate de = lambdaExpr.Compile();
// MethodInfo method = de.Method;
Console.WriteLine(de.DynamicInvoke(paramslist));
return string.Format(getTemplate, paramslist);
}
private static int available(ref int max, ref StringBuilder formula)
{
int temp = 0;
if (max > 0)
{
Random randomVariable = new Random();
if (max == 1)
{
temp = randomVariable.Next(0, max + 1);
}
else
{
temp = randomVariable.Next(0, max);
}
max = max - temp;
}
formula.AppendFormat("{0}+", temp);
return temp;
static List<ParameterExpression>  paramenterArray=new List<ParameterExpression>() ;
///<summary>
///
///</summary>
///<param name="lenght">累加次数</param>
///<param name="resultLeft">默认累加表达式</param>
///<returns></returns>
private static BinaryExpression addExpression(int lenght, BinaryExpression resultLeft)
{
try
{
ParameterExpression left, right;
left = Expression.Parameter(typeof(int), string.Format("left{0}", lenght) );
right = Expression.Parameter(typeof(int), string.Format("right{0}", (lenght - 1)) );
BinaryExpression result = Expression.Add(left, right);
if (lenght > 2)
{
paramenterArray.Add(left);
paramenterArray.Add(right);
if (resultLeft != null)
result = Expression.Add(resultLeft, addExpression(lenght - 2, result));
else
result = addExpression(lenght - 2, result);
}
if (lenght == 2)
{
paramenterArray.Add(left);
paramenterArray.Add(right);
if (resultLeft != null)
result = Expression.Add(resultLeft, result);
else
{
/
/ignore;
}
}
if (lenght == 1)
{
if (resultLeft != null)
{
ParameterExpression rExpression = Expression.Parameter(typeof(int), string.Format("right{0}", lenght ));                        paramenterArray.Add(rExpression);
result = Expression.Add(resultLeft, rExpression);
}
else
{
throw (new Exception("当lenght等于1时,resultLeft参数不能为空"));
}
}
return result;
}
catch ( Exception ex)
{
#if DEBUG
Console.WriteLine(ex.StackTrace.ToString());
#endif
throw (ex);
}
}
}
}
收录君的四则混合运算写法。Pop(), Push(opt) ,Peek()的范例。
public class Calculator
{
public Calculator()
{
_OptStack = new Stack<char>();
_SuffixStack = new Stack<float>();
}
private Stack<char> _OptStack;
private Stack<float> _SuffixStack;
public float Calculate(string expression)
{
string lastNum = string.Empty;
for (int i = 0; i < expression.Length; i++)
if (char.IsNumber(expression[i]) || expression[i].Equals('.'))                {
lastNum += expression[i];
}
typeof array
else
{
if (lastNum != string.Empty)
{
Merger(float.Parse(lastNum));
lastNum = string.Empty;
}
AddOpt(expression[i]);
}
}
if (lastNum != string.Empty)
{
Merger(float.Parse(lastNum));
}
while (_OptStack.Count > 0)
{
Merger(_OptStack.Pop());
}
return _SuffixStack.Pop();
}
private void AddOpt(char opt)
{
if (_OptStack.Count == 0)
{
_OptStack.Push(opt);
return;
}
if (opt.Equals(')'))
{
while (!_OptStack.Peek().Equals('('))
{
Merger(_OptStack.Pop());
}
_OptStack.Pop();
return;
}
char tempOpt = _OptStack.Peek();
if ((opt.Equals('-') || opt.Equals('+')) &&
(tempOpt.Equals('*') || tempOpt.Equals('/')))
{
while (_OptStack.Count > 0)
{
Merger(_OptStack.Pop());
}
}
_OptStack.Push(opt);
}
private void Merger(float exp)
{
_SuffixStack.Push(exp);
}
private void Merger(char exp)
{
float num1 = _SuffixStack.Pop();
float num2 = _SuffixStack.Pop();
float result = 0;
switch (exp)
{
case'+':
result = num2 + num1;
break;
case'-':
result = num2 - num1;
break;
case'*':
result = num2 * num1;
break;
case'/':
result = num2 / num1;
break;
}
_SuffixStack.Push(result);
}
}
//调⽤写法
//string calc = "89+(126/2)*3-6/3+(96+3-8/2)";// 随便写四则运算    //Calculator calculator = new Calculator();
//MessageBox.Show(calculator.Calculate(calc).ToString()); // 结果

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。