想当年的编笆达人 发表于 2023-6-27 14:01:42

计算数学算式的值

实现语言: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(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
 

来源:https://www.cnblogs.com/lwcdi/archive/2023/06/27/17508214.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 计算数学算式的值