字符串封装数学表达式解析器

//*******************************************************************

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;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值