//*******************************************************************
string str = “45*(10.3+34/(3+1))”;
var p = Math.Evaluator.MathExpressionValue(str);
Console.WriteLine§;
//**************************************************************
///
/// 字符串封装数学表达式解析器
///
public class Evaluator
{
public static Double MathExpressionValue(string MathExpress)
{
List ListExp = null;
try
{
ListExp = Parse(PreTreat(MathExpress));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
}
return Calculate(ListExp);
}
/// <summary>
/// 预处理字符串表达式
/// </summary>
/// <param name="exp"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
private static string PreTreat(string exp)
{
if (string.IsNullOrEmpty(exp))
{
throw new Exception("表达式为空");
}
exp = exp.Replace(" ", "").Replace("\t", "").Replace("\r", "").Replace("\n", "");
if (string.IsNullOrEmpty(exp))
{
throw new Exception("表达式为空");
}
if (!IsBracketMatch(exp))
{
throw new Exception("左右括号不匹配");
}
return exp;
}
/// <summary>
/// 是否前后括号匹配
/// </summary>
/// <param name="exp"></param>
/// <returns></returns>
private static bool IsBracketMatch(string exp)
{
var str1 = exp.Replace("(", "");
var leftCount = exp.Length - str1.Length;
var str2 = exp.Replace(")", "");
var rightCount = exp.Length - str2.Length;
if (leftCount == rightCount)
return true;
return false;
}
/// <summary>
/// 检查字符是否是操作符
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
private static bool IsOperand(string str)
{
string[] operators = { "+", "-", "*", "/", "(", ")" };
for (int i = 0; i < operators.Length; i++)
if (str == operators[i])
return false;
return true;
}
/// <summary>
/// 栈是否为空
/// </summary>
/// <param name="st"></param>
/// <returns></returns>
private static bool IsEmpty(Stack st)
{
return st.Count == 0 ? true : false;
}
/// <summary>
/// 以操作符分割字符串
/// </summary>
/// <param name="StrSource"></param>
/// <returns></returns>
public static List<string> StringSpit(string StrSource)
{
char[] strarray = StrSource.ToCharArray();
List<string> ListStr = new List<string>();
int start = 0;
int LastOpIndex = 0;
string temp;
for (int i = 0; i < strarray.Length; i++)
{
switch (strarray[i])
{
case '+':
case '-':
case '*':
case '/':
case '(':
case ')':
temp = StrSource.Substring(start, i - start);
if (!string.IsNullOrEmpty(temp))
{
ListStr.Add(temp);
}
temp = StrSource.Substring(i, 1);
if (!string.IsNullOrEmpty(temp))
{
ListStr.Add(temp);
}
start = i + 1;
LastOpIndex = i;
break;
}
if (i == strarray.Length - 1)
{
ListStr.Add(StrSource.Substring(LastOpIndex + 1, strarray.Length - LastOpIndex - 1));
}
}
return ListStr;
}
/// <summary>
/// 获取操作员优先级
/// </summary>
/// <param name="Opr"></param>
/// <returns></returns>
private static int Priority(string Opr)
{
int priority;
switch (Opr)
{
case "+":
priority = 1;
break;
case "-":
priority = 1;
break;
case "*":
priority = 2;
break;
case "/":
priority = 2;
break;
default:
priority = 0;
break;
}
return priority;
}
/// <summary>
/// 计算后缀表达式值
/// </summary>
/// <param name="ListstrA"></param>
/// <returns></returns>
public static double Calculate(List<string> ListstrA)
{
if (ListstrA == null)
return 0;
double numFir, numSec, ret;
string temp;
Stack myStack = new System.Collections.Stack();
foreach (string str in ListstrA)
{
temp = str;
if (IsOperand(temp))//如果是数字则入栈
{
myStack.Push(temp);
}
else //如果是运算符则计算
{
object obNum1 = myStack.Pop();
numFir = double.Parse(obNum1.ToString());
object obNum2 = myStack.Pop();
numSec = double.Parse(obNum2.ToString());
ret = GetValue(temp, numFir, numSec);
myStack.Push(ret);
}
}
return (double)myStack.Pop();
}
/// <summary>
/// 获取后缀表达式
/// </summary>
/// <param name="segments"></param>
/// <returns></returns>
public static List<string> Parse(string MathExpressions)
{
int i, j = 0;
string temp, tempSec;
Stack myStack = new System.Collections.Stack();
List<string> listResult = new List<string>();
List<string> strListA = StringSpit(MathExpressions);
string[] strB = new string[strListA.Count];
foreach (string strch in strListA)
{
temp = strch;
if (IsOperand(temp))
{
strB[j++] = temp;
}
else
{
if (temp == "(")
myStack.Push(temp);
else if (temp == ")")
{
while (!IsEmpty(myStack))//出栈直到遇到”(“
{
temp = (string)myStack.Pop();
if (temp == "(")
break;
else
strB[j++] = temp;
}
}
else
{
if (!IsEmpty(myStack))
{
do
{
tempSec = (string)myStack.Pop();
if (Priority(temp) > Priority(tempSec))
{
myStack.Push(tempSec);
myStack.Push(temp);
break;
}
else
{
strB[j++] = tempSec;
if (IsEmpty(myStack))
{
myStack.Push(temp);
break;
}
}
} while (!IsEmpty(myStack));
}
else
{
myStack.Push(temp);
}
}
}
}
while (!IsEmpty(myStack))
strB[j++] = (string)myStack.Pop();
for (i = 0; i < strB.Length; i++)
{
if (!string.IsNullOrEmpty(strB[i]))
{
listResult.Add(strB[i]);
}
}
return listResult;
}
/// <summary>
/// 根据操作符计算数值
/// </summary>
/// <param name="op"></param>
/// <param name="numFir"></param>
/// <param name="numSec"></param>
/// <returns></returns>
private static double GetValue(string op, double numFir, double numSec)
{
switch (op)
{
case "+":
return numSec + numFir;
case "-":
return numSec - numFir;
case "*":
return numSec * numFir;
case "/":
return numSec / numFir;
default:
return 0;
}
}
}