SHARE
TWEET

Exercise07Expression

g-stoyanov Jan 21st, 2013 107 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*Write a program that calculates the value of given arithmetical expression. The expression can contain the following elements only:
  2. *Real numbers, e.g. 5, 18.33, 3.14159, 12.6
  3. *Arithmetic operators: +, -, *, / (standard priorities)
  4. *Mathematical functions: ln(x), sqrt(x), pow(x,y)
  5. *Brackets (for changing the default priorities)
  6. *Examples:
  7. *(3+5.3) * 2.7 - ln(22) / pow(2.2, -1.7) ---> ~ 10.6
  8. *pow(2, 3.14) * (3 - (3 * sqrt(2) - 3.2) + 1.5*0.3) ---> ~ 21.22
  9. *Hint: Use the classical "shunting yard" algorithm and "reverse Polish notation".*/
  10.  
  11. using System;
  12. using System.Globalization;
  13. using System.Text;
  14. using System.Threading;
  15.  
  16. public class Exercise07Expression
  17. {
  18.     private static void Main()
  19.     {
  20.         Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
  21.         Console.Write("\nPlease enter expression like this (3+5.3) * 2.7 - ln(22) / pow(2.2, -1.7) : ");
  22.         string test = Console.ReadLine();
  23.         StringBuilder expression = new StringBuilder();
  24.         expression.Append('(', 2);
  25.         foreach (var item in test)
  26.         {
  27.             if (item != ' ')
  28.             {
  29.                 expression.Append(item);
  30.             }
  31.         }
  32.  
  33.         expression.Append(')', 2);
  34.  
  35.         while (SearchBrackets(expression) != 0)
  36.         {
  37.             expression = CalculateExpression(true, SearchBrackets(expression), expression);
  38.         }
  39.  
  40.         Console.WriteLine("\n\nResult is: {0}\n\n", expression);
  41.     }
  42.  
  43.     private static decimal ExtractNum(int offset, int startPoint, StringBuilder expression)
  44.     {
  45.         int temp = 0;
  46.         StringBuilder result = new StringBuilder();
  47.         startPoint += offset;
  48.         if (expression[startPoint] == '-' || expression[startPoint] == '+')
  49.         {
  50.             result.Append(expression[startPoint]);
  51.             startPoint += offset;
  52.         }
  53.  
  54.         while (int.TryParse(expression[startPoint].ToString(), out temp) || expression[startPoint] == '.')
  55.         {          
  56.             if (offset == -1)
  57.             {
  58.                 result.Insert(0, expression[startPoint]);
  59.             }
  60.             else
  61.             {
  62.                 result.Append(expression[startPoint]);
  63.             }
  64.  
  65.             if (startPoint > 0 && startPoint < expression.Length - 1)
  66.             {
  67.                 startPoint += offset;
  68.             }
  69.             else
  70.             {
  71.                 break;
  72.             }
  73.         }
  74.  
  75.         bool check = expression[startPoint + offset] == '*' || expression[startPoint + offset] == '/' || expression[startPoint + offset] == '+' || expression[startPoint + offset] == '-';
  76.         if (offset == -1 && ((expression[startPoint] == '+' && check) || (expression[startPoint] == '-' && check)))
  77.         {
  78.             result.Insert(0, expression[startPoint]);
  79.         }
  80.  
  81.         return decimal.Parse(result.ToString());
  82.     }
  83.  
  84.     private static StringBuilder Calculate(int startPoint, StringBuilder expression)
  85.     {
  86.         decimal result = 0;
  87.         switch (expression[startPoint])
  88.         {
  89.             case '-':
  90.                 {
  91.                     result = ExtractNum(-1, startPoint, expression) - ExtractNum(1, startPoint, expression);
  92.                     return Exchange(startPoint - ExtractNum(-1, startPoint, expression).ToString().Length, startPoint + ExtractNum(1, startPoint, expression).ToString().Length + 1, result.ToString(), expression);
  93.                 }
  94.  
  95.             case '+':
  96.                 {
  97.                     result = ExtractNum(-1, startPoint, expression) + ExtractNum(1, startPoint, expression);
  98.                     return Exchange(startPoint - ExtractNum(-1, startPoint, expression).ToString().Length, startPoint + ExtractNum(1, startPoint, expression).ToString().Length + 1, result.ToString(), expression);
  99.                 }
  100.  
  101.             case '*':
  102.                 {
  103.                     result = ExtractNum(-1, startPoint, expression) * ExtractNum(1, startPoint, expression);
  104.                     return Exchange(startPoint - ExtractNum(-1, startPoint, expression).ToString().Length, startPoint + ExtractNum(1, startPoint, expression).ToString().Length + 1, result.ToString(), expression);
  105.                 }
  106.  
  107.             default:
  108.                 {
  109.                     result = ExtractNum(-1, startPoint, expression) / ExtractNum(1, startPoint, expression);
  110.                     return Exchange(startPoint - ExtractNum(-1, startPoint, expression).ToString().Length, startPoint + ExtractNum(1, startPoint, expression).ToString().Length + 1, result.ToString(), expression);
  111.                 }
  112.         }
  113.     }
  114.  
  115.     private static StringBuilder Exchange(int startIndex, int endIndex, string valueToExchange, StringBuilder expression)
  116.     {
  117.         expression.Remove(startIndex, endIndex - startIndex);
  118.         expression.Insert(startIndex, valueToExchange);
  119.         return expression;
  120.     }
  121.  
  122.     private static StringBuilder CalculateFunc(int startIndex, StringBuilder expression)
  123.     {
  124.         CalculateExpression(false, startIndex, expression);
  125.         decimal result = 0;
  126.         switch (expression[startIndex - 1])
  127.         {
  128.             case 'n':
  129.                 {
  130.                     result = (decimal)Math.Log((double)ExtractNum(1, startIndex, expression));
  131.                     return Exchange(startIndex - 2, startIndex + ExtractNum(1, startIndex, expression).ToString().Length + 2, result.ToString(), expression);
  132.                 }
  133.  
  134.             case 't':
  135.                 {
  136.                     result = (decimal)Math.Sqrt((double)ExtractNum(1, startIndex, expression));
  137.                     return Exchange(startIndex - 4, startIndex + ExtractNum(1, startIndex, expression).ToString().Length + 2, result.ToString(), expression);
  138.                 }
  139.  
  140.             default:
  141.                 {
  142.                     int startIndex2 = startIndex;
  143.                     while (expression[startIndex2] != ',')
  144.                     {
  145.                         startIndex2++;
  146.                     }
  147.  
  148.                     result = (decimal)Math.Pow((double)ExtractNum(-1, startIndex2, expression), (double)ExtractNum(1, startIndex2, expression));
  149.                     return Exchange(startIndex - 3, startIndex + ExtractNum(-1, startIndex2, expression).ToString().Length + ExtractNum(1, startIndex2, expression).ToString().Length + 3, result.ToString(), expression);
  150.                 }
  151.         }
  152.     }
  153.  
  154.     private static int SearchBrackets(StringBuilder expression)
  155.     {
  156.         int index = 0;
  157.         int result = 0;
  158.         while (index < expression.Length && expression[index] != ')')
  159.         {
  160.             if (expression[index] == '(')
  161.             {
  162.                 result = index;
  163.             }
  164.  
  165.             index++;
  166.         }
  167.  
  168.         return result;
  169.     }
  170.  
  171.     private static StringBuilder CalculateExpression(bool checkForFunc, int startIndex, StringBuilder expression)
  172.     {
  173.         if (checkForFunc)
  174.         {
  175.             int mod = 1;
  176.             if (startIndex == 0)
  177.             {
  178.                 mod = 0;
  179.             }
  180.  
  181.             if (expression[startIndex - mod] == 'n' || expression[startIndex - mod] == 't' || expression[startIndex - mod] == 'w')
  182.             {
  183.                 return CalculateFunc(startIndex, expression);
  184.             }
  185.         }
  186.  
  187.         while (SearchSign('*', startIndex, expression) != 0)
  188.         {
  189.             expression = Calculate(SearchSign('*', startIndex, expression), expression);
  190.         }
  191.  
  192.         while (SearchSign('/', startIndex, expression) != 0)
  193.         {
  194.             expression = Calculate(SearchSign('/', startIndex, expression), expression);
  195.         }
  196.  
  197.         while (SearchSign('-', startIndex, expression) != 0 || SearchSign('+', startIndex, expression) != 0)
  198.         {
  199.             while (SearchSign('+', startIndex, expression) != 0)
  200.             {
  201.                 if (SearchSign('-', startIndex, expression) != 0 && (SearchSign('-', startIndex, expression) < SearchSign('+', startIndex, expression)))
  202.                 {
  203.                     break;
  204.                 }
  205.  
  206.                 expression = Calculate(SearchSign('+', startIndex, expression), expression);
  207.             }
  208.  
  209.             while (SearchSign('-', startIndex, expression) != 0)
  210.             {
  211.                 expression = Calculate(SearchSign('-', startIndex, expression), expression);
  212.             }
  213.         }
  214.  
  215.         if (checkForFunc)
  216.         {
  217.             expression.Remove(startIndex, 1);
  218.             while (expression[startIndex] != ')')
  219.             {
  220.                 startIndex++;
  221.             }
  222.  
  223.             expression.Remove(startIndex, 1);
  224.         }
  225.        
  226.         return expression;
  227.     }
  228.  
  229.     private static int SearchSign(char sign, int startIndex, StringBuilder expression)
  230.     {
  231.         int resultIndex = 0;
  232.         while (expression[startIndex] != ')' && startIndex < expression.Length)
  233.         {
  234.             bool check = expression[startIndex - 1] == '*' || expression[startIndex - 1] == '/' || expression[startIndex - 1] == '+' || expression[startIndex - 1] == '-' || expression[startIndex - 1] == ',' || expression[startIndex - 1] == '(';
  235.             if (expression[startIndex] == sign &&  !check)
  236.             {
  237.                 resultIndex = startIndex;
  238.                 break;
  239.             }
  240.  
  241.             startIndex++;
  242.         }
  243.  
  244.         return resultIndex;
  245.     }
  246. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top