Advertisement
vlad0

Shunting Yard

Jan 23rd, 2013
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.21 KB | None | 0 0
  1. using System;
  2. using System.Linq;
  3. using System.Collections.Generic;
  4. using System.Text;
  5.  
  6. class AlgorithmExpression
  7. {
  8.     static string output = String.Empty;
  9.     static string stack = String.Empty;
  10.  
  11.     static void Main()
  12.     {
  13.         //string expression = "12/(3-1+8)*4";
  14.         string expression = "pow(2, (3.14-10)*4*(-1)) * (3 - (3 * sqrt(2) - 3.2) + 1.5*0.3) ";
  15.         //string expression = "1+ln(-10*5)";
  16.         double result = DoTheShunting(expression);
  17.         Console.WriteLine("Expression: {0}",expression);
  18.         Console.WriteLine("Result: {0}",result);
  19.     }
  20.  
  21.     private static double DoTheShunting(string expression)
  22.     {
  23.        
  24.         expression = DealWithUnaryMinus(expression);
  25.         expression = DealWithFunctions(expression);
  26.         output = String.Empty;
  27.         stack = String.Empty;
  28.         expression = DealWithUnaryMinus(expression);
  29.         string beforeCalculations = GoThroughExpreesion(expression); //here we get the output
  30.         double result = Calculate(beforeCalculations); //we do some maths on it :)
  31.  
  32.         return result;
  33.     }
  34.  
  35.     private static string DealWithFunctions(string expression)
  36.     {
  37.         int length = expression.Length;
  38.        
  39.        
  40.         for (int i = 0; i < length; i++)
  41.         {
  42.             if (expression[i] == 'l' && expression[i+1] == 'n') //check for ln(x) function
  43.             {
  44.  
  45.                 string function = GetFunctionBody(expression, ref i, 2);
  46.                 double result = DoTheShunting(function);
  47.                 double functionResult = NaturalLog(result);
  48.                 string replaceFunction = "ln" + function.ToString();
  49.                 string newFunction = "(" + functionResult.ToString() + ")";
  50.                 expression = expression.Replace(replaceFunction, newFunction);
  51.             }
  52.             else if (expression[i] == 's' && expression[i + 1] == 'q')
  53.             {
  54.                 string function = GetFunctionBody(expression, ref i, 4);
  55.                 double result = DoTheShunting(function);
  56.                 double functionResult = Square(result);
  57.                 string replaceFunction = "sqrt" + function.ToString();
  58.                 string newFunction = "(" + functionResult.ToString() + ")";
  59.                 expression = expression.Replace(replaceFunction, newFunction);
  60.             }
  61.             else if (expression[i] == 'p' && expression[i+1] == 'o')
  62.             {
  63.                 string function = GetFunctionBody(expression, ref i, 3);
  64.                 string[] powParameters = function.Split(',');
  65.                 powParameters[0] = powParameters[0].Remove(0,1); //remove the left '('
  66.                 powParameters[1] = powParameters[1].Remove(powParameters[1].Length-1, 1); //remove the right')'
  67.                 double numberForPow = DoTheShunting(powParameters[0]);
  68.                 double powerForPow = DoTheShunting(powParameters[1]);
  69.                 double functionResult = DoPow(numberForPow,powerForPow);
  70.                 string replaceFunction = "pow" + function.ToString();
  71.                 string newFunction = "(" + functionResult.ToString() + ")";
  72.                 expression = expression.Replace(replaceFunction, newFunction);
  73.             }
  74.         }
  75.  
  76.         return expression;
  77.     }
  78.  
  79.     private static double DoPow(double numberForPow, double powerForPow)
  80.     {
  81.         return Math.Pow(numberForPow, powerForPow);
  82.     }
  83.  
  84.     private static double Square(double result)
  85.     {
  86.         return Math.Sqrt(result);
  87.     }
  88.  
  89.     private static string GetFunctionBody(string expression, ref int i, int position)
  90.     {
  91.         StringBuilder function = new StringBuilder();
  92.         int openBrackets = 0;
  93.         int closingBrackets = 0;
  94.         openBrackets++;
  95.         function.Append(expression[i + position]);
  96.         i = i + position+1;//get to the first char after '('
  97.         while (i < expression.Length && openBrackets != closingBrackets )
  98.         {
  99.             if (expression[i] == '(')
  100.             {
  101.                 openBrackets++;
  102.             }
  103.             else if (expression[i] == ')')
  104.             {
  105.                 closingBrackets++;
  106.             }
  107.  
  108.             function.Append(expression[i]);
  109.             i++;
  110.         }
  111.         return function.ToString();
  112.     }
  113.  
  114.     private static double NaturalLog(double function)
  115.     {
  116.         return Math.Log(function, 2.71828);
  117.     }
  118.  
  119.     private static string DealWithUnaryMinus(string expression)
  120.     {
  121.         expression = expression.Replace(" ", ""); //ignore whitespaces
  122.         expression = expression.Replace("(-", "(0-"); //deal with unary operators
  123.         expression = expression.Replace(",-", ",0-");//deal with unary operators in functions
  124.         expression = expression.Replace("(+", "(0+"); //deal with unary operators
  125.         expression = expression.Replace(",+", ",0+"); ////deal with unary operators in functions
  126.  
  127.        
  128.  
  129.         if (expression[0] == '-' || expression[0] == '+')
  130.         {
  131.             expression = '0' + expression;
  132.         }
  133.         return expression;
  134.     }
  135.  
  136.     private static double Calculate(string beforeCalculations)
  137.     {
  138.         List<double> finalStack = new List<double>();
  139.         char[] charSeparators = {' '};
  140.         string[] elements = beforeCalculations.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries);
  141.         double temp;
  142.         bool successParse;
  143.         double result=0;
  144.        
  145.             for (int i = 0; i < elements.Length; i++)
  146.             {
  147.                 temp = 0;
  148.                 result = 0;
  149.  
  150.                 successParse = double.TryParse(elements[i], out temp);
  151.  
  152.                 if (successParse)
  153.                 {
  154.                     finalStack.Add(temp);
  155.                 }
  156.                 else
  157.                 {
  158.                     int length = finalStack.Count;
  159.                     result = MakeArithmetics(finalStack[length - 2], finalStack[length - 1], elements[i]);
  160.                     finalStack.RemoveRange(length - 2, 2);
  161.                     finalStack.Add(result);
  162.                 }
  163.  
  164.                 result = finalStack[0];
  165.             }
  166.  
  167.         return result;
  168.  
  169.     }
  170.  
  171.     private static string GoThroughExpreesion(string expression)
  172.     {
  173.         int length = expression.Length;
  174.         for (int i = 0; i < length; i++)
  175.         {
  176.             if ((expression[i] >= '0' && expression[i] <= '9')|| expression[i] == '.')
  177.             {
  178.                 PushToOutput(expression[i]);
  179.             }
  180.             else if (expression[i] == ')')
  181.             {
  182.                 ClearStack();
  183.             }
  184.             else
  185.             {
  186.                 output += ' ';
  187.                 CheckStack(expression[i]);
  188.             }
  189.         }
  190.  
  191.         for (int i = stack.Length-1; i>= 0; i--)
  192.         {
  193.             output+=' ';
  194.             PushToOutput(stack[i]);
  195.         }
  196.  
  197.         return output;
  198.     }
  199.  
  200.     private static void ClearStack()
  201.     {
  202.         for (int i = stack.Length - 1; i >= 0; i--)
  203.         {
  204.             if (stack[i] != '(')
  205.             {
  206.                 output += ' ';
  207.                 PushToOutput(stack[i]);
  208.             }
  209.             else
  210.             {
  211.                 stack = stack.Remove(i, stack.Length - i);
  212.                 break;
  213.             }
  214.         }
  215.     }
  216.  
  217.     private static void CheckStack(char lastToken)
  218.     {
  219.         int length = stack.Length;
  220.         if (length == 0)
  221.         {
  222.             PushtToStack(lastToken);
  223.         }
  224.         else
  225.         {
  226.             int lastTokenPresedence = GetPrecedence(lastToken);
  227.             int previousTokenPresedence = GetPrecedence(stack[length-1]);
  228.  
  229.             if (lastToken!='(' && lastTokenPresedence<=previousTokenPresedence)
  230.             {
  231.                 PushToOutput(stack[length - 1]); //push the smaller presedence to output
  232.                 output += ' ';
  233.                 stack = stack.Remove(length - 1, 1);
  234.                 PushtToStack(lastToken);
  235.                
  236.             }
  237.             else
  238.             {
  239.                 PushtToStack(lastToken);
  240.             }
  241.         }
  242.     }
  243.  
  244.     private static double MakeArithmetics(double firstNumber, double secondNumber, string Token)
  245.     {
  246.         switch (Token)
  247.         {
  248.             case "*": return firstNumber * secondNumber;
  249.                 break;
  250.             case "/": return firstNumber / secondNumber;
  251.                 break;
  252.             case "+": return firstNumber + secondNumber;
  253.                 break;
  254.             case "-": return firstNumber - secondNumber;
  255.                 break;
  256.             case "(": return 0;
  257.                 break;
  258.             default: return 0;
  259.                 break;
  260.  
  261.                 return 0;
  262.         }
  263.     }
  264.  
  265.     private static int GetPrecedence(char Token)
  266.     {
  267.         switch (Token)
  268.         {
  269.             case '*': return 3;
  270.                 break;
  271.             case '/': return 3;
  272.                 break;
  273.             case '+': return 2;
  274.                 break;
  275.             case '-': return 2;
  276.                 break;
  277.             case '(': return 0;
  278.                 break;
  279.             default: return 0;
  280.                 break;
  281.         }
  282.     }
  283.  
  284.     private static void PushtToStack(char Token)
  285.     {
  286.         stack = stack + Token;
  287.     }
  288.  
  289.     private static void PushToOutput(char Token)
  290.     {
  291.         output = output + Token;
  292.     }
  293.  
  294. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement