本文主要是介绍使用C#代码计算数学表达式实例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
《使用C#代码计算数学表达式实例》这段文字主要讲述了如何使用C#语言来计算数学表达式,该程序通过使用Dictionary保存变量,定义了运算符优先级,并实现了EvaluateExpression方法来...
C#代码计算数学表达式
此程序展示了如何使用 C# 代码来计算数学表达式。
该程序以 以下代码开始。
此代码声明了一个Dictionary
,稍后将使用它来保存变量。(例如,如果用户想要 A = 10、B = 3 和 Pi = 3.14159265。)
然后它定义了一个Precedence
枚举来表示运算符的优先级。例如,乘法的优先级高于加法。
单击“EvaLuate”按钮时,程序会复制您输入到“ Primatives Dictionary
”中的任何基元,然后调用EvaluateExpression
方法,该方法会执行所有有趣的工作。
该方法很长,因此我将分段描述
// Stores user-entered primitives like X = 10. private Dictionary<string, string> Primatives; private enum Precedence { None = 11, Unary = 10, // Not actually used. Power = 9, // We use ^ to mean exponentiation. Times = 8, Div = 7, Modulus = 6, Plus = 5, }
// Evaluate the expression. private double EvaluateExpression(string expression) { int best_pos = 0; int parens = 0; // Remove all spaces. string expr = expression.Replace(" ", ""); int expr_len = expr.Length; if (expr_len == 0) return 0; // If we find + or - now, then it's a unary operator. bool is_unary = true; // So far we have nothing. Precedence best_prec = Precedence.None; // Find the operator with the lowest precedence. // Look for places where there are no open // parentheses. for (int pos = 0; pos < expr_len; pos++) { // Examine the next character. string ch = expr.Substring(pos, 1); // Assume we will not find an operator. In // that case, the next operator will not // be unary. bool next_unary = pythonfalse; if (ch == " ") { // Just skip spaces. We keep them here // to make the error messages easier to } else if (ch == "(") { // Increase the open parentheses count. parens += 1; // A + or - after "(" is unary. next_unary = true; } else if (ch == ")") { // Decrease the open parentheses count. parens -= 1; // An operator after ")" is not unary. next_unary = false; // if parens < 0, too many )'s. if (parens < 0) throw new FormatException( "Too many close parentheses in '" + expression + "'"); } else if (parens == 0) { // See if this is an operator. if ((ch == "^") || (ch == "*") || (ch == "/") || (ch == "\\") || (ch == "%") || (ch == "+") || (ch == "-")) { // An operator after an operator // is unary. next_unary = true; // See if this operator has higher // precedence than the current one. switch (ch) { case "^": if (best_prec >= Precedence.Power) { best_prec = Precedence.Power; best_pos = pos; } break; case "*": case "/": if (best_prec >= Precedence.Times) { best_prec = Precedence.Times; best_pos = pos; } break; case "%": if (best_prec >= Precedence.Modulus) { best_prec = Precedence.Modulus; best_pos = pos; } break; case "+": case "-": // Ignore unary operators // for now. if ((!is_unary) && www.chinasem.cn best_prec >= Precedence.Plus) { best_prec = Precedence.Plus; best_pos = pos; } break; } // End switch (ch) } // End if this is an operator. } // else if (parens == 0) is_unary = next_unary; } // for (int pos = 0; pos < expr_len; pos++)
该方法的这一部分用于查找表达式中优先级最低的运算符。为此,它只需循环遍历表达式,检查其运算符字符,并确定它们的优先级是否低于先前找到的运算符。
下面的代码片段显示了下一步
// If the parentheses count is not zero, // there's a ) missing. if (parens != 0) { throw new FormatException( "Missing close parenthesis in '" + expression + "'"); } // Hopefully we have the operator. if (best_prec < Precedence.None) { string lexpr = expr.Substring(0, best_pos); string rexpr = expr.Substring(best_pos + 1); switch (expr.Substring(best_pos, 1)) { case "^": return Math.Pow( EvaluateExpression(lexpr), EvaluateExpression(rexpr)); case "*": return EvaluateExpression(lexpr) * EvaluateExpression(rexpr); case "/": return EvaluateExpression(lexpr) / EvaluateExpression(rexpr); case "%": return EvaluateExpression(lexpr) % Evaluatewww.chinasem.cnExpression(rexpr); case "+": return EvaluateExpression(lexpr) + EvaluateExpression(rexpr); case "-": return EvaluateExpression(lexpr) - EvaluateExpression(rexpr); } }
如果括号未闭合,该方法将引发异常。否则,它会使用优先级最低的运算符作为分界点,将表达式拆分成多个部分。然后,它会递归调用自身来评估子表达式,并使用适当的操作来合并结果。
例如,假设表达式为 2 * 3 + 4 * 5。那么优先级最低的运算符是 +。该函数将表达式分解为 2 * 3 和 4 * 5,并递归调用自身来计算这些子表达式的值(得到 6 和 20),然后使用加法将结果合并(得到 26)。
以下代码显示该方法如何处理函数调用
// if we do not yet have an operator, there
// are several possibilities:
//
// 1. expr is (expr2) for some expr2.
// 2. expr is -expr2 or +expr2 for some expr2.
// 3. expr is Fun(expr2) for a function Fun.
// 4. expr is ajs primitive.
// 5. It's a literal like "3.14159".
// Look for (expr2).
if (expr.StartsWith("(") & expr.EndsWith(")"))
{
// Remove the parentheses.
return EvaluateExpression(expr.Substring(1, expr_len - 2));
}
// Look for -expr2.
if (expr.StartsWith("-"))
{
return -EvaluateExpression(expr.Substring(1));
}
// Look for +expr2.
if (expr.StartsWith("+"))
{
return EvaluateExpression(expr.Substring(1));
}
// Look for Fun(expr2).
if (expr_len > 5 & expr.EndsWith(")"))
{
// Find the first (.
int paren_pos = expr.IndexOf("(");
if (paren_poshttp://www.chinasem.cn > 0)
{
// See what the function is.
string lexpr = expr.Substring(0, paren_pos);
string rexpr = expr.Substring(paren_pos + 1,
expr_len - paren_pos - 2);
switch (lexpr.ToLower())
{
case "sin":
return Math.Sin(EvaluateExpression(rexpr));
case "cos":
return Math.Cos(EvaluateExpression(rexpr));
case "tan":
return Math.Tan(EvaluateExpression(rexpr));
case "sqrt":
return Math.Sqrt(EvaluateExpression(rexpr));
case "factorial":
return Factorial(EvaluateExpression(rexpr));
// Add other functions (including
// program-defined functions) here.
}
}
}
此代码检查表达式是否以 ( 开头并以 结尾。如果是,则删除这些括号并计算表达式的其余部分。
接下来,代码确定表达式是否以一元 + 或 - 运算符开头。如果是,程序将计算不带运算符的表达式,如果运算符为 -,则对结果取反。
然后,代码会查找Sin
、Cos
和Factorial
等函数。如果找到,它会调用该函数并返回结果。(下载示例以查看Factorial函数。)您可以类似地添加其他函数。
以下代码显示了该方法的其余部分
// See if it's a primitive. if (Primatives.ContainsKey(expr)) { // Return the corresponding value, // converted into a Double. try { // Try to convert the expression into a value. return double.Parse(Primatives[expr]); } catch (Exception) { throw new FormatException( "Primative '" + expr + "' has value '" + Primatives[expr] + "' which is not a Double."); } } // It must be a literal like "2.71828". try { // Try to convert the expression into a Double. return double.Parse(expr); } catch (Exception) { throw new FormatException( "Error evaluating '" + expression + "' as a constant."); } }
如果表达式仍未求值,则它必须是您在文本框中输入的原始值或数值。
代码将检查原始字典以查看表达式是否存在。
如果值在字典中,则代码获取其值,将其转换为双精度值,然后返回结果。
总结
这篇关于使用C#代码计算数学表达式实例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!