首页 > 解决方案 > 我试图在 C# 控制台中制作一个计算器

问题描述

我希望用户输入一个数学方程作为字符串,而不是将它们拆分为 chars 然后将它们转换为 double 以便我可以使用它们,但我无法将 char 转换为 double

public  void Cal()
        {
            Console.WriteLine("Enter the transaction without spaces");
            string transaction = Console.ReadLine();
            char[] characters = transaction.ToArray();

            for(int i = 0; i < characters.Length; i++)
            {
                Console.Write(characters[i] + " ");
                if (i % 2 == 1)
                {
                    Convert.ToDouble(characters[i]);
                }
            }
            
        }
static void Main(string[] args)
        {
            Calculate calc = new Calculate();
            bool quit = false;
            
            while (quit == false)
            {
                calc.Cal();
                Console.ReadLine();
                Console.WriteLine("to clear pres C to quit the app pres Q");
                Console.Write(" : ");
                string b = Console.ReadLine().ToUpper();
                if (b == "C")
                {
                    Console.Clear();
                }else 
                {

                    quit = true;
                    Console.ReadLine();

                }
            }
        }

标签: c#arraysconsole

解决方案


如果您想要一个非常简单的数学评估器,您应该先通过 char[] 来识别运算符。然后,您可以通过将运算符之间或单个运算符之外的 char[] 段转换为数值类型,并将它们作为每个运算符的操作数传递并显示结果来评估表达式。如果您支持括号括起来,那就更复杂了。(见下文)

要在运算符之间转换 char[] 段,因为您使用的是 C#,您可以:

  • 使用您的字符串“事务”并调用 .Substring(startidx, endidx) 将其限制在运算符之前或之间,然后调用 .Trim() 删除空格并返回一个字符串。例如:“string expression = transaction.Substring(0, opidx-1).Trim()” 该字符串(数字的)可以发送到 double.Parse() 函数以返回您可以评估的双精度值使用以这种方式解析和转换的运算符和其他值。例如:“double val = double.Parse(expression)”。

  • 或者您可以调用一个函数将范围内的每个字符索引步进到运算符,使用 char.IsNumber() 来查找非空白范围的开始和结束,然后不妨使用事务字符串和 .Substring使用这些索引输出包含要解析的数字的字符串,如上所示,使用 double.Parse()。否则,您可以将数字字符附加到字符串中。

如果您想要一个功能更强大的公式和表达式解析器,则需要更复杂地处理它。

我曾经写过一个 C# 代码解析器,包括一个完整的数学表达式/公式解析器。解析可能复杂的数学表达式是数学评估软件程序的重要步骤。括号会影响评估的顺序。

基本上,除了识别注释和文字区域(特定于代码解析器)之外,我采取的步骤是:

  • 从您的表达式中创建一个开放和匹配的右括号索引数组。递归函数是最有效的。调用 FindCloseParan 函数,为其提供开放参数索引,如果它在超出它的关闭参数之前找到一个开放参数,它将再次调用 FindCloseParan,否则它可以返回关闭参数字符,允许您存储每个开放参数的匹配相同数组中的水平关闭参数。然后,您可以稍后调用 GetCloseParan 函数以获取开放参数索引以检索其匹配级别关闭参数索引,而不必重复使用可能效率低下(重叠工作重复)的递归 FindCloseParan 函数,并且您可以使用匹配打开和关闭 paran 索引以在每个区域中运行解析表达式函数。(如果你想要一个没有括号支持的简单数学评估器,

  • 运行一个函数来解析逻辑表达式。它应该识别运算符的下一个索引(或 AND 或 OR),并查看它是否在下一个打开的参数之前。如果下一个运算符索引在一个开放参数之后,它应该在与开放参数相同的参数级别上搜索关闭参数之后的下一个运算符。如果它发现任何参数之外,它应该调用解析逻辑表达式函数来解析每个运算符每一侧的表达式。如果没有运算符,它可以解析块以将其存储为表达式类类型。如果在同一个参数外壳级别有多个运算符,它可以将每个运算符类型的索引存储在一个运算符数组中,以及一个与运算符交错的表达式类型数组。(表达式、运算符、表达式、运算符、表达式等)

识别可能是运算符的第一个字符的字符会导致检查可能的两个字符运算符。从我的代码:

CSharpTypeWalker.firstcharoperatorsarray = new char[] { '+', '-', '~', '*', '/', '%', '^', '!', '&', '|', ' <', '>', '=', '?' };

CSharpTypeWalker.alloperatorsarray = new string[] { "+", "-", "~", "*", "/", "%", "^", "!", "&", "|", " <"、">"、"<<"、">>"、"&&"、"||"、"=="、"!="、"<="、"=>"、">=" , "=<", "?:", "+=", "-=", "++", "--" };


推荐阅读