您的位置:首页 > 编程语言 > C#

C#算术表达式的计算

2009-12-07 17:53 253 查看
最近在项目中做了一个自定义属性相关的,其中有个自定义属性是一个计算列,通过客户设定计算表达式来完成数据的自动录入,在网上也看了些相关的好的算法,其中最经典的当属《逆波兰式》
相关文章请参考:/article/7013188.html
由于时间关系,做一个中缀表达式的计算运用在项目中,现贴下code仅供参考:

其中传入的自己先去掉首位空格,并且数字和运算符之间用空格分隔

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;
using System.Collections;

namespace ADOnline.Web.Common
{
/// <summary>
/// 计算表达式运算类
/// </summary>
public class ArithmeticExpressions
{
/// <summary>
/// 获取中缀表达式
/// </summary>
/// <param name="exp">计算表达式(数字与运算符用空格分隔)</param>
/// <returns></returns>
public static List<string> getColuExpression(string exp)
{
System.Text.ASCIIEncoding asc = new System.Text.ASCIIEncoding();
Stack st = new Stack();
string[] temp = exp.Split(' ');
List<string> value = new List<string>();

for (int i = 0; i < temp.Length; i++)
{
int num = (int)asc.GetBytes(temp[i])[0];
if (num < 48 && num > 39)
{
if (st.Count > 0)
{
string operatorStr = st.Peek().ToString();
if (temp[i] == "*" || temp[i] == "/")
{
if (temp[i + 1] == "(")
{
st.Push(temp[i]);
continue;
}
else
{
if (operatorStr == "(")
{
st.Push(temp[i]);
continue;
}
else if (operatorStr == "*" || operatorStr == "/")
{
value.Add(st.Pop().ToString());
st.Push(temp[i]);
continue;
}
else
{
st.Push(temp[i]);
continue;
}
}
}
else if (temp[i] == "+" || temp[i] == "-")
{
if (operatorStr == "(")
{
st.Push(temp[i]);
continue;
}
else
{
value.Add(st.Pop().ToString());
if (st.Count > 0 && st.Peek().ToString() != "(")
{
value.Add(st.Pop().ToString());
}
st.Push(temp[i]);
continue;
}
}
else if (temp[i] == "(")
{
st.Push(temp[i]);
continue;
}
else
{
if (i + 1 == temp.Length)
{
value.Add(st.Pop().ToString());
st.Pop();
while (st.Count > 0)
value.Add(st.Pop().ToString());
break;
}
else
{
value.Add(st.Pop().ToString());
st.Pop();
continue;
}
}
}
else
{
st.Push(temp[i]);
continue;
}
}
else if (i + 1 == temp.Length)
{
value.Add(temp[i]);
value.Add(st.Pop().ToString());
while (st.Count > 0)
value.Add(st.Pop().ToString());
break;
}
else
{
value.Add(temp[i]);
continue;
}
}
return value;
}

/// <summary>
/// 获取计算表达式的值
/// </summary>
/// <param name="expression">中缀表达式数组</param>
/// <returns></returns>
public static double CalculateResult(string expre)
{
List<string> temp = getColuExpression(expre);
try
{
while (temp.Count > 1)
{
for (int i = 0; i < temp.Count; i++)
{
double resultTemp = 0;
if (temp[i] == "+")
resultTemp = Convert.ToDouble(temp[i - 2]) + Convert.ToDouble(temp[i - 1]);
else if (temp[i] == "-")
resultTemp = Convert.ToDouble(temp[i - 2]) - Convert.ToDouble(temp[i - 1]);
else if (temp[i] == "*")
resultTemp = Convert.ToDouble(temp[i - 2]) * Convert.ToDouble(temp[i - 1]);
else if (temp[i] == "/")
resultTemp = Convert.ToDouble(temp[i - 2]) / Convert.ToDouble(temp[i - 1]);
else
continue;
temp[i - 2] = resultTemp.ToString();
temp.RemoveAt(i);
temp.RemoveAt(i - 1);
break;
}
}
}
catch (Exception ex)//计算表达式的值错误,导致无法运算
{
temp.Clear();
temp.Add("0");
}
return Convert.ToDouble(temp[0]);
}
}
}


说明:该表达式中只涉及到+ - * 、 ( ) ,所以判断的时候是用了ASCII直接判断是否为这些运算符。

以上示例仅供参考,转载请注明出处!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: