110,535
社区成员
发帖
与我相关
我的任务
分享
/// <summary>
/// 公式预处理
/// </summary>
/// <param name="formula">公式</param>
/// <param name="name">名称</param>
/// <param name="value">对应值</param>
/// <returns>公式计算结果</returns>
private static decimal Regular(string formula, string[] name, decimal[] value)
{
for (int i = 0; i < name.Length; i++)
{
formula = formula.Replace(name[i], value[i].ToString());
}
char[] chs = formula.ToCharArray();
string[] strs=new string[chs.Length];
for(int i=0;i<chs.Length;i++)
{
strs[i] = chs[i].ToString();
}
Stack Digital = new Stack();//存储数字
Stack Operator = new Stack();//存储运算符
string operaters = "+-*/()%";
foreach (string str in strs)
{
if (str.Equals(string.Empty)) continue;//如果为空继续
if (operaters.IndexOf(str) != -1)//是操作符
{
if (str.Equals("("))
{
Operator.Push(str);//进栈
}
else
{
Calculat(Digital, Operator, str);
}
}
else//不是操作符
{
Digital.Push(decimal.Parse(str));
}
}
if (Operator.Count != 0) Calculat(Digital, Operator, ")");//计算栈中剩余部分
return (decimal)Digital.Pop();
}
/// <summary>
/// 计算
/// </summary>
/// <param name="str">操作符</param>
private static void Calculat(Stack Digital, Stack Operator, string str)
{
if (Operator.Count == 0)
{
Operator.Push(str);
return;//已经没有运算符了
}
string prev = (string)Operator.Peek();
if (prev == null || prev.Equals(string.Empty)) return;//元素不存在
if (prev.Equals("("))
{
if (str.Equals(")"))
{
Operator.Pop();//移除操作符
return;
}
else
{
Operator.Push(str);//进栈
}
}
else
if (compareOperater(str) <= compareOperater(prev))//第一个操作符等级小于等于第二个,则进行运算
{
Operator.Pop();//移除操作符
switch (prev)
{
case "+"://进行加操作
{
decimal num1 = (decimal)Digital.Pop();//返回第一个元素
decimal num2 = (decimal)Digital.Pop();//返回第二个元素
Digital.Push(num2 + num1);
}
break;
case "-":
{
decimal num1 = (decimal)Digital.Pop();//返回第一个元素
decimal num2 = (decimal)Digital.Pop();//返回第二个元素
Digital.Push(num2 - num1);
}
break;
case "*":
{
decimal num1 = (decimal)Digital.Pop();//返回第一个元素
decimal num2 = (decimal)Digital.Pop();//返回第二个元素
Digital.Push(num2 * num1);
}
break;
case "/":
{
decimal num1 = (decimal)Digital.Pop();//返回第一个元素
decimal num2 = (decimal)Digital.Pop();//返回第二个元素
Digital.Push(num2 / num1);
}
break;
case "%":
{
decimal num1 = (decimal)Digital.Pop();//返回第一个元素
Digital.Push(num1 / 100);
}
break;
}
Calculat(Digital, Operator, str);//继续比较
}
else
{
Operator.Push(str);//进栈
}
}
/// <summary>
/// 运算符级别
/// </summary>
/// <param name="operater">操作符</param>
/// <returns></returns>
private static int compareOperater(string operater)
{
string str3 = "(";
string str2 = "*/%";
string str1 = "+-";
string str0 = ")";
if (str0.IndexOf(operater) != -1) return 0;//零级运算符
if (str1.IndexOf(operater) != -1) return 1;//一级运算符
if (str2.IndexOf(operater) != -1) return 2;//二级运算符
if (str3.IndexOf(operater) != -1) return 3;//三级运算符
return -1;
}
static void Main(string[] args)
{
//公式
string formula = "C*2-B+L";
//这边上下关系对应,送C=3之类的也可以,做个转换
string[] name = new string[] { "C", "B", "L" };
decimal[] value = new decimal[]{ 3, 5, 3};
//完成表达式计算
decimal Y = Regular(formula, name, value);
for(int i=0;i<name.Length;i++)
Console.WriteLine("{0}={1}", name[i], value[i]);
Console.WriteLine("Y={0}={1}",formula,Y);
Console.ReadLine();
}
string GongShi = "Y=C*2-B+L";
decimal C, B, L, Y;
C = B = L = 3;
string temp = Regex.Replace(GongShi, "(?<![CBL])(?:(C)|(B)|(L))(?![CBL])", delegate(Match m)
{
return m.Groups[1].Success ? C.ToString() : (m.Groups[2].Success ? B.ToString() : L.ToString());
});
temp = temp.Substring(temp.IndexOf("Y=") + 2);
Y = Convert.ToDecimal(new DataTable().Compute(temp, ""));
Console.WriteLine(Y);