StringMathCalculator/Calculator.cs
/// <summary>
/// Reorder the operations in the opertionsOrder Queue by weight of operation
/// </summary>
/// <param name="operationOrder">Queue of operations</param>
/// <returns>CalculatorCalculation ready for calculations to be executed</returns>
Reorder the operations in the opertionsOrder Queue by weight of operation
Reorder the operations in the opertionsOrder Queue by weight of operation
private CalculatorCalculation OrderCalculations(Queue<object> operationOrder)
        {
            var originCalculator = new CalculatorCalculation();
            var currentCalculator = originCalculator;
            var parenthesesStack = new Stack<CalculatorCalculation>();
            foreach(object operation in operationOrder)
            {
                if (operation is OperationCalc operationCalc)
                {
                    var rightCalculator = new CalculatorNumber(operationCalc.X);
                    currentCalculator.Right = rightCalculator;
                    if (operation is OperationPair operationPair)
                    {
                        currentCalculator.PairCalc = operationPair.CalcPair;
                        currentCalculator.Weight = operationPair.Weight;
                    }
                    else if (operation is OperationNum)
                    {
                        currentCalculator.Weight = -1;
                    }
                }
                else
                {
                    var operationParentheses = (OperationParentheses)operation;
                    if(operationParentheses.Parentheses == Parentheses.RIGHT)
                    {
                        currentCalculator.Weight = -1;
                        currentCalculator.Right = new CalculatorCalculation()
                        {
                            Top = currentCalculator
                        };
                        parenthesesStack.Push(currentCalculator);
                        currentCalculator = (CalculatorCalculation) currentCalculator.Right;
                        continue;
                    }
                    else
                    {
                        var rightParentheses = parenthesesStack.Pop();
                        if(operationParentheses.calcPair != null)
                        {
                            rightParentheses.Weight = operationParentheses.Weight;
                            rightParentheses.PairCalc = operationParentheses.calcPair;
                            currentCalculator = rightParentheses;
                        }
                        else
                        {
                            var tempTop = (CalculatorCalculation)rightParentheses.Top;
                            if (tempTop != null)
                            {
                                tempTop.Left = rightParentheses;
                            }
                            continue;
                        }
                    }
                }
                var topCalculator = (CalculatorCalculation)currentCalculator.Top;
                if(topCalculator != null)
                {
                    if(topCalculator.Weight != -1 && currentCalculator.Weight != -1)
                    {
                        if(currentCalculator.Weight < topCalculator.Weight)
                        {
                            var tempCurrentCalculator = currentCalculator;
                            var tempTopCalculator = topCalculator;
                            while (tempCurrentCalculator.Weight < tempTopCalculator.Weight)
                            {
                                var newTopCalculator = new CalculatorCalculation()
                                {
                                    PairCalc = tempCurrentCalculator.PairCalc,
                                    Right = tempTopCalculator,
                                    Top = tempTopCalculator.Top
                                };
                                tempTopCalculator.Left = tempCurrentCalculator.Right;
                                tempTopCalculator.Top = newTopCalculator;
                                if (originCalculator == tempTopCalculator)
                                {
                                    originCalculator = newTopCalculator;
                                }
                                tempCurrentCalculator = newTopCalculator;
                                tempTopCalculator = (CalculatorCalculation)tempCurrentCalculator.Top;
                                if(tempTopCalculator != null)
                                {
                                    if(tempTopCalculator.Weight != -1)
                                    {
                                        tempTopCalculator.Left = newTopCalculator;
                                    }
                                    else
                                    {
                                        tempTopCalculator.Right = newTopCalculator;
                                    }
                                }
                                else
                                {
                                    break;
                                }
                            }
                            currentCalculator = tempCurrentCalculator;
                        }
                        else
                        {
                            if (topCalculator.Weight != -1)
                            {
                                topCalculator.Left = currentCalculator;
                            }
                        }
                    }
                    else
                    {
                        if (topCalculator.Weight != -1)
                        {
                            topCalculator.Left = currentCalculator;
                        }
                    }
                }
                currentCalculator = new CalculatorCalculation()
                {
                    Top =  currentCalculator
                };
            }
            return originCalculator;
        }
private CalculatorCalculation OrderCalculations ( Queue < object > operationOrder ) { var originCalculator = new CalculatorCalculation ( ) ; var currentCalculator = originCalculator ; var parenthesesStack = new Stack < CalculatorCalculation > ( ) ; foreach ( object operation in operationOrder ) { if ( operation is OperationCalc operationCalc ) { var rightCalculator = new CalculatorNumber ( operationCalc . X ) ; currentCalculator . Right = rightCalculator ; if ( operation is OperationPair operationPair ) { currentCalculator . PairCalc = operationPair . CalcPair ; currentCalculator . Weight = operationPair . Weight ; } else if ( operation is OperationNum ) { currentCalculator . Weight = - 1 ; } } else { var operationParentheses = ( OperationParentheses ) operation ; if ( operationParentheses . Parentheses == Parentheses . RIGHT ) { currentCalculator . Weight = - 1 ; currentCalculator . Right = new CalculatorCalculation ( ) { Top = currentCalculator } ; parenthesesStack . Push ( currentCalculator ) ; currentCalculator = ( CalculatorCalculation ) currentCalculator . Right ; continue ; } else { var rightParentheses = parenthesesStack . Pop ( ) ; if ( operationParentheses . calcPair != null ) { rightParentheses . Weight = operationParentheses . Weight ; rightParentheses . PairCalc = operationParentheses . calcPair ; currentCalculator = rightParentheses ; } else { var tempTop = ( CalculatorCalculation ) rightParentheses . Top ; if ( tempTop != null ) { tempTop . Left = rightParentheses ; } continue ; } } } var topCalculator = ( CalculatorCalculation ) currentCalculator . Top ; if ( topCalculator != null ) { if ( topCalculator . Weight != - 1 && currentCalculator . Weight != - 1 ) { if ( currentCalculator . Weight < topCalculator . Weight ) { var tempCurrentCalculator = currentCalculator ; var tempTopCalculator = topCalculator ; while ( tempCurrentCalculator . Weight < tempTopCalculator . Weight ) { var newTopCalculator = new CalculatorCalculation ( ) { PairCalc = tempCurrentCalculator . PairCalc , Right = tempTopCalculator , Top = tempTopCalculator . Top } ; tempTopCalculator . Left = tempCurrentCalculator . Right ; tempTopCalculator . Top = newTopCalculator ; if ( originCalculator == tempTopCalculator ) { originCalculator = newTopCalculator ; } tempCurrentCalculator = newTopCalculator ; tempTopCalculator = ( CalculatorCalculation ) tempCurrentCalculator . Top ; if ( tempTopCalculator != null ) { if ( tempTopCalculator . Weight != - 1 ) { tempTopCalculator . Left = newTopCalculator ; } else { tempTopCalculator . Right = newTopCalculator ; } } else { break ; } } currentCalculator = tempCurrentCalculator ; } else { if ( topCalculator . Weight != - 1 ) { topCalculator . Left = currentCalculator ; } } } else { if ( topCalculator . Weight != - 1 ) { topCalculator . Left = currentCalculator ; } } } currentCalculator = new CalculatorCalculation ( ) { Top = currentCalculator } ; } return originCalculator ; }
Reorder the operations in the opertionsOrder Queue by weight of operation
Reorder the operations in the opertionsOrder Queue by weight of operation
//The originCalculator is the top of the binary tree structure for the operations order //The current calculation, start with the origin //The stack for determining the current parentheses we are in //Loop through all the opearations and order them according to the order of operations //Put the number associated with the operation to the right of the tree as a single number //If the Operation is an OperationNum, don't assign a calculation //and make the weight -1 so its operation order is never checked //Operation is an OperationParentheses //Check if operation is a right parentheses //Set the parentheses calculation with a weight -1 so its operation order is never checked //The operation is a left parentheses //If extraneous parentheses surround the given string operation the top calculation //will end up as a parentheses, and subsequently have no left operation //Check if there is a calculation above the current parentheses, otherwise don't add to left. //The CalculatorCalculation above the current CalculationCalculator in the binary tree //Check if we are on the originCalculator //Don't change operations order if the currentCalculator is a OperationNum //If the currentCalculators weight is less than it's top weight, sink the top to its right //Loop until the weights have been reordered //Create a newTopCalculator to replace the current Top calculator //The current Top calculator will sink to the new Top calculators right //and the new Top calculators operation will become the operation of the current calculator //If the current Top calculator was the origin, make the new Top calculator the new origin //Make the current calculator the newTopCalculator to check if the new Top calculator //has a weight less than the new Top calculators Top. //If there is no Top calculator break the loop //If the weights were already ordered, add the currentCalculator to the left of the Top //Don't add to the left if the topCalculator has the weight of a parentheses //If the current calculator is a OperationNum, add the currentCalculator to the left of the Top //Don't add to the left if the topCalculator has the weight of a parentheses //Setup the currentCalculator as the new Top for the next CalculationCalculator in the loop
CalculatorCalculation ready for calculations to be executed
CalculatorCalculation ready for calculations to be executed
operationOrder
Queue<object>
Queue of operations
Queue of operations