计算数学算式的值

打印 上一主题 下一主题

主题 530|帖子 530|积分 1605

实现语言:C#
 
思路:
1.括号里面的计算优先级最高,首先计算出括号里面的值;
2.将所有的括号值计算完成后,将得到不包含括号的数学算式A;
3.数学算式A按先乘除后加减的优先级计算处结果。
 
使用单的技术:
在解析数据算式过程中使用栈结构,可以比较方便比配左右括号。
 

///

/// 计算表达式的值

/// 例子:3/3-[(1/2)+(2*3)]*(1+2)*100+100

///

///

///

public static decimal CalculateExpression(this string expressionInput)

{

    try

    {

        string expression = expressionInput.RemoveNewLineAndSpace();

        Stack stack = new Stack(1000);

        List startChars = new List(4) { '(', '[', '{' };

        List endChars = new List(4) { ')', ']', '}' };

        foreach (char item in expression)

        {

            if (!endChars.Contains(item))

            {

                stack.Push(item);

                continue;

            }

            StringBuilder childExpression = new StringBuilder();

            while (true)

            {

                if (stack.Count < 1) break;

                char expressionContent = stack.Pop();

                if (startChars.Contains(expressionContent)) break;

                childExpression.Insert(0, expressionContent);

            }

            decimal tempResult = CalculateSimpleExpression(childExpression.ToString());

            //Replace("-","|") 处理负数运算

            tempResult.ToString().Replace("-", "|").ToCharArray().ToList().ForEach(c => stack.Push(c));

        }

        StringBuilder simpleExpression = new StringBuilder();

        while (stack.Count > 0)

        {

            simpleExpression.Insert(0, stack.Pop());

        }

        return CalculateSimpleExpression(simpleExpression.ToString());

    }

    catch

    {

        throw new Exception("计算表达式的值报错");

    }

}

 

 

///

/// 计算简单表达式的值

/// 不能包含括号

///

///

///

private static decimal CalculateSimpleExpression(string exp)

{

    if (decimal.TryParse(exp, out decimal r))

    {

        return r;

    }

    if (exp.StartsWith("-") || exp.StartsWith("+"))

    {

        exp = $"0{exp}";

    }

    List operateCodes = new List(4) { '+', '-', '*', '/' };

    List items = new List();

    StringBuilder itemStr = new StringBuilder();

    exp.ToArray().ToList().ForEach(item => {

        if (!operateCodes.Contains(item))

        {

            itemStr.Append(item);

            return;

        }

        items.Add(itemStr.ToString().Replace("|", "-"));//Replace("-","|") 处理负数运算

        items.Add(item.ToString());

        itemStr.Clear();

    });

    items.Add(itemStr.ToString().Replace("|", "-"));

 

    // originalValues:原始项  operates:操作符

    Func CalExpression = (originalValues, operates) =>

    {

        Stack calculatingExpression = new Stack(16);

        foreach (string item in originalValues)

        {

            bool existOperateCode = operates.Count(c => calculatingExpression.Contains(c)) > 0 ? true : false;

            if (existOperateCode == false)

            {

                calculatingExpression.Push(item);

                continue;

            }

            var cal = new Dictionary();

            cal.Add("*", (a, b) => a * b);

            cal.Add("/", (a, b) => a / b);

            cal.Add("+", (a, b) => a + b);

            cal.Add("-", (a, b) => a - b);

            decimal tempValue = cal[calculatingExpression.Pop()](decimal.Parse(calculatingExpression.Pop()), decimal.Parse(item));

            calculatingExpression.Push(tempValue.ToString());

        }

        return calculatingExpression;

    };

    //先计算乘除

    items = CalExpression(items, new List() { "*", "/" }).ToList();

    items.Reverse();

    //先计算加减

    var resultStack = CalExpression(items, new List() { "+", "-" });

    return decimal.Parse(resultStack.Pop());

}
 
验证:
"3/3-[(1/2)+(2*3)]*(1+2)*100+100".CalculateExpression();
结果:-1849
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

大连全瓷种植牙齿制作中心

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表