我怎样才能制作一个带有使用多个操作和括号的字符串的计算器? C#
How can i make a calculator with string that uses multiple operations and brackets? C#
我的计算器在没有括号的情况下几乎可以完美运行(它有一些错误)。此计算器可以进行多项运算(例如 12+345*2-100 //602)。
我希望将括号和其中的字符串替换为结果,然后继续计算。
我怎样才能修复括号的方法使其按预期工作?
计算步骤:
- 找到一个符号
- 找到符号周围的数字
- 进行计算并用字符串中的结果替换数字和符号
- 检查任何符号,如果有则重新开始
给出数学题的结果
//Finds numbers around an symbol
static void FindNumbers(string equation, int start, char symbol)
{
number1 = 0;
number2 = 0;
number1String = string.Empty;
number2String = string.Empty;
if (equation[start] == symbol)
{
for (int j = start - 1; j >= 0; j--)//Finds left number around the symbol
{
if (char.IsDigit(equation[j]))
{
number1String = equation[j] + number1String;
}
else
{
break;
}
}
for (int j = start + 1; j < equation.Length; j++)//Finds right number around the symbol
{
if (char.IsDigit(equation[j]))
{
number2String += equation[j];
}
else
{
break;
}
}
number1 = int.Parse(number1String);
number2 = int.Parse(number2String);
}
return;
}
//Devision and Multiplication
static void Priority1(string equation, int start)
{
for (int i = start; i < equation.Length; i++)//Multiplication
{
if (equation[i] == '*')
{
symbol = equation[i];
FindNumbers(equation, i, symbol);
currentresult = number1 * number2;
equation = equation.Replace(number1.ToString() + symbol + number2.ToString(),
currentresult.ToString());
}
}
for (int i = 0; i < equation.Length; i++)//Devision
{
if (equation[i] == '/')
{
symbol = equation[i];
FindNumbers(equation, i, symbol);
currentresult = number1 / number2;
equation = equation.Replace(number1.ToString() + symbol + number2.ToString(),
currentresult.ToString());
}
}
Priority2(equation, 0);
}
//Addition and Devision
static void Priority2(string equation, int start)
{
for (int i = start; i < equation.Length; i++)//Addition
{
if (equation[i] == '+')
{
symbol = equation[i];
FindNumbers(equation, i, symbol);
currentresult = number1 + number2;
equation = equation.Replace(number1.ToString() + symbol + number2.ToString(),
currentresult.ToString());
}
}
for (int i = 0; i < equation.Length; i++)//Devision
{
if (equation[i] == '-')
{
symbol = equation[i];
FindNumbers(equation, i, symbol);
currentresult = number1 - number2;
equation = equation.Replace(number1.ToString() + symbol + number2.ToString(),
currentresult.ToString());
}
}
for (int i = 0; i < equation.Length; i++)//Checks if there are more symbols in the string
{
if (char.IsSymbol(equation[i]))
{
Priority1(equation, 0);
}
}
tempresult = equation;
Console.WriteLine("Result : " + equation);
}
//Brackets
static void Brackets(string equation, int index)
{
for (int i = index; index < equation.Length; index++)
{
if (equation[index] == '(')
{
index += 1;
Brackets(equation, index);
for (int j = index; j < equation.Length; j++)
{
if (equation[j] == ')')
{
tempresult = temp;
Console.WriteLine("..." + tempresult);
break;
}
temp += equation[j];
}
Priority1(tempresult, index);
equation = equation.Replace('(' + temp.ToString() + ')', tempresult.ToString());
Console.WriteLine("." + equation);
}
}
Priority1(equation, 0);
}
static void Main(string[] args)
{
equation = Console.ReadLine();
Brackets(equation, 0);
Console.ReadKey();
}
你的代码现在理论上知道如何解析和评估正确的简单数学表达式。通过简单的表达式,我指的是仅由已知的一元和二元运算符和数字组成的表达式(无括号)
您现在尝试解析的表达式是:
- 一个简单的表达式
- 带括号的表达式
- 由简单表达式和括号表达式组成的复杂表达式
如果是案例#1,那么你已经知道如何处理了;解析它,你就完成了。
如果是情况 #2,只需删除括号并解析其中的表达式。
如果是第 3 种情况,那么你将获取顶级括号内的表达式并解析它们;您将进入第 1 步或第 2 步或第 3 步,嘿!你猜怎么着?你已经知道如何处理这些了。
最终你会把你的表达式分解成简单的表达式。然后你只需要在回来的路上回溯评估。
用简单的英语来说,你需要一个递归解析器;一个可以调用自身并解析和评估嵌套表达式的解析器。
考虑例如:
e0: 1 + (2 * (3 - 2))
- e0: 你解析
1 + p0
- p0: 你解析
2 * p1
- p1: 你解析
3 - 2
- 您已完成解析
- p1:计算结果为
1
- p0:计算结果为
2
- e0:计算结果为
3
- 你完成了。
很酷的是解析器理论上可以处理无限嵌套表达式...问题是您的计算机可能不能。
您可能想要研究将字符串方程分解成单独的标记,并使用类似 Shunting-Yard-Algorithm 的东西来 parse/calculate 结果。
我的计算器在没有括号的情况下几乎可以完美运行(它有一些错误)。此计算器可以进行多项运算(例如 12+345*2-100 //602)。 我希望将括号和其中的字符串替换为结果,然后继续计算。 我怎样才能修复括号的方法使其按预期工作?
计算步骤:
- 找到一个符号
- 找到符号周围的数字
- 进行计算并用字符串中的结果替换数字和符号
- 检查任何符号,如果有则重新开始
给出数学题的结果
//Finds numbers around an symbol static void FindNumbers(string equation, int start, char symbol) { number1 = 0; number2 = 0; number1String = string.Empty; number2String = string.Empty; if (equation[start] == symbol) { for (int j = start - 1; j >= 0; j--)//Finds left number around the symbol { if (char.IsDigit(equation[j])) { number1String = equation[j] + number1String; } else { break; } } for (int j = start + 1; j < equation.Length; j++)//Finds right number around the symbol { if (char.IsDigit(equation[j])) { number2String += equation[j]; } else { break; } } number1 = int.Parse(number1String); number2 = int.Parse(number2String); } return; } //Devision and Multiplication static void Priority1(string equation, int start) { for (int i = start; i < equation.Length; i++)//Multiplication { if (equation[i] == '*') { symbol = equation[i]; FindNumbers(equation, i, symbol); currentresult = number1 * number2; equation = equation.Replace(number1.ToString() + symbol + number2.ToString(), currentresult.ToString()); } } for (int i = 0; i < equation.Length; i++)//Devision { if (equation[i] == '/') { symbol = equation[i]; FindNumbers(equation, i, symbol); currentresult = number1 / number2; equation = equation.Replace(number1.ToString() + symbol + number2.ToString(), currentresult.ToString()); } } Priority2(equation, 0); } //Addition and Devision static void Priority2(string equation, int start) { for (int i = start; i < equation.Length; i++)//Addition { if (equation[i] == '+') { symbol = equation[i]; FindNumbers(equation, i, symbol); currentresult = number1 + number2; equation = equation.Replace(number1.ToString() + symbol + number2.ToString(), currentresult.ToString()); } } for (int i = 0; i < equation.Length; i++)//Devision { if (equation[i] == '-') { symbol = equation[i]; FindNumbers(equation, i, symbol); currentresult = number1 - number2; equation = equation.Replace(number1.ToString() + symbol + number2.ToString(), currentresult.ToString()); } } for (int i = 0; i < equation.Length; i++)//Checks if there are more symbols in the string { if (char.IsSymbol(equation[i])) { Priority1(equation, 0); } } tempresult = equation; Console.WriteLine("Result : " + equation); } //Brackets static void Brackets(string equation, int index) { for (int i = index; index < equation.Length; index++) { if (equation[index] == '(') { index += 1; Brackets(equation, index); for (int j = index; j < equation.Length; j++) { if (equation[j] == ')') { tempresult = temp; Console.WriteLine("..." + tempresult); break; } temp += equation[j]; } Priority1(tempresult, index); equation = equation.Replace('(' + temp.ToString() + ')', tempresult.ToString()); Console.WriteLine("." + equation); } } Priority1(equation, 0); } static void Main(string[] args) { equation = Console.ReadLine(); Brackets(equation, 0); Console.ReadKey(); }
你的代码现在理论上知道如何解析和评估正确的简单数学表达式。通过简单的表达式,我指的是仅由已知的一元和二元运算符和数字组成的表达式(无括号)
您现在尝试解析的表达式是:
- 一个简单的表达式
- 带括号的表达式
- 由简单表达式和括号表达式组成的复杂表达式
如果是案例#1,那么你已经知道如何处理了;解析它,你就完成了。
如果是情况 #2,只需删除括号并解析其中的表达式。
如果是第 3 种情况,那么你将获取顶级括号内的表达式并解析它们;您将进入第 1 步或第 2 步或第 3 步,嘿!你猜怎么着?你已经知道如何处理这些了。
最终你会把你的表达式分解成简单的表达式。然后你只需要在回来的路上回溯评估。
用简单的英语来说,你需要一个递归解析器;一个可以调用自身并解析和评估嵌套表达式的解析器。
考虑例如:
e0: 1 + (2 * (3 - 2))
- e0: 你解析
1 + p0
- p0: 你解析
2 * p1
- p1: 你解析
3 - 2
- 您已完成解析
- p1:计算结果为
1
- p0:计算结果为
2
- e0:计算结果为
3
- 你完成了。
很酷的是解析器理论上可以处理无限嵌套表达式...问题是您的计算机可能不能。
您可能想要研究将字符串方程分解成单独的标记,并使用类似 Shunting-Yard-Algorithm 的东西来 parse/calculate 结果。