-
计算数学算式的值
实现语言:C#
思路:
1.括号里面的计算优先级最高,首先计算出括号里面的值;
2.将所有的括号值计算完成后,将得到不包含括号的数学算式A;
3.数学算式A按先乘除后加减的优先级计算处结果。
使用单的技术:
在解析数据算式过程中使用栈结构,可以比较方便比配左右括号。
/// <summary>
/// 计算表达式的值
/// 例子:3/3-[(1/2)+(2*3)]*(1+2)*100+100
/// </summary>
/// <param name="expressionInput"></param>
/// <returns></returns>
public static decimal CalculateExpression(this string expressionInput)
{
try
{
string expression = expressionInput.RemoveNewLineAndSpace();
Stack<char> stack = new Stack<char>(1000);
List<char> startChars = new List<char>(4) { '(', '[', '{' };
List<char> endChars = new List<char>(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("计算表达式的值报错");
}
}
/// <summary>
/// 计算简单表达式的值
/// 不能包含括号
/// </summary>
/// <param name="exp"></param>
/// <returns></returns>
private static decimal CalculateSimpleExpression(string exp)
{
if (decimal.TryParse(exp, out decimal r))
{
return r;
}
if (exp.StartsWith("-") || exp.StartsWith("+"))
{
exp = $"0{exp}";
}
List<char> operateCodes = new List<char>(4) { '+', '-', '*', '/' };
List<string> items = new List<string>();
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<List<string>, List<string>, Stack<string>> CalExpression = (originalValues, operates) =>
{
Stack<string> calculatingExpression = new Stack<string>(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<string, Func<decimal, decimal, decimal>>();
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<string>() { "*", "/" }).ToList();
items.Reverse();
//先计算加减
var resultStack = CalExpression(items, new List<string>() { "+", "-" });
return decimal.Parse(resultStack.Pop());
}
验证:
"3/3-[(1/2)+(2*3)]*(1+2)*100+100".CalculateExpression();
结果:-1849
出处:https://www.cnblogs.com/lwcdi/p/17508214.html