@pat.wasiewiczPiszemy trochę bardziej złożony kalkulator w C#.NET - #3 - Refactoring
Piszemy trochę bardziej złożony kalkulator w C#.NET - #3 - Refactoring
26.04.2013 00:40
Po batach o złych wcięciach (klik! ) poprawiam trochę kod: mam nadzieję, że jest trochę czytelniejszy.
Mógłbym podzelić go na mniejsze metody, ale myślę że w takiej formie sam algorytm (link w poprzednim poście) będzie trochę prostszy do wyczytania z kodu.
public static Expression FromInfix(string input) { var output = new List<string>(); var operators = new Stack<char>(); // dzielimy ciągiem białych znaków var arguments = Regex.Split(input, @"\s+"); foreach (var symbol in arguments) { // jeżeli dostaliśmy liczbę albo cokolwiek innego niż operator if (!Regex.IsMatch(symbol, @"^[\+|\*|/|(|)]$")) { output.Add(symbol); continue; } var exprOperator = Convert.ToChar(symbol); if (exprOperator.Equals('(')) { operators.Push(exprOperator); continue; } if (exprOperator.Equals(')')) { var leftBracket = operators.Pop(); while (!leftBracket.Equals('(')) { output.Add(leftBracket.ToString()); leftBracket = operators.Pop(); } continue; } if (!exprOperator.Equals('*') && !exprOperator.Equals('+') && !exprOperator.Equals('/')) { continue; } // stos pusty albo operator na wierzchołku ma mniejszy priorytet if (operators.Count == 0 || GetPriority(operators.Peek()) < GetPriority(exprOperator)) { operators.Push(exprOperator); continue; } var top = operators.Peek(); // zdejmij wszystkie operatory o wiekszym bądź równym priorytecie // i zapisz na wyjściu while (GetPriority(top) >= GetPriority(exprOperator) && operators.Count > 0) { output.Add(top.ToString()); operators.Pop(); top = operators.Peek(); } // wrzuć na stos aktualny operator operators.Push(exprOperator); } // jeśli jakiś operator został na stosie, też go zapisz na wyjściu if (operators.Count == 1) { output.Add(operators.Peek().ToString()); } // usuń pierwszą spację var expression = string.Join(" ", output.ToArray()); return FromOnp(expression); }