Advertisement
g-stoyanov

Exercise07Expression ver 2

Jan 23rd, 2013
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.88 KB | None | 0 0
  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 (offset > 0 && (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.                 if ((expression[startPoint - 1] == '-' || expression[startPoint - 1] == '+') && !int.TryParse(expression[startPoint - 2].ToString(), out temp))
  60.                 {
  61.                     result.Insert(0, expression[startPoint - 1]);
  62.                 }
  63.             }
  64.             else
  65.             {
  66.                 result.Append(expression[startPoint]);
  67.             }
  68.  
  69.             if (startPoint > 0 && startPoint < expression.Length - 1)
  70.             {
  71.                 startPoint += offset;
  72.             }
  73.             else
  74.             {
  75.                 break;
  76.             }
  77.         }
  78.  
  79.         return decimal.Parse(result.ToString());
  80.     }
  81.  
  82.     private static StringBuilder Calculate(int startPoint, StringBuilder expression)
  83.     {
  84.         decimal result = 0;
  85.         switch (expression[startPoint])
  86.         {
  87.             case '-':
  88.                 {
  89.                     result = ExtractNum(-1, startPoint, expression) - ExtractNum(1, startPoint, expression);
  90.                     return Exchange(startPoint - ExtractNum(-1, startPoint, expression).ToString().Length, startPoint + ExtractNum(1, startPoint, expression).ToString().Length + 1, result.ToString(), expression);
  91.                 }
  92.  
  93.             case '+':
  94.                 {
  95.                     result = ExtractNum(-1, startPoint, expression) + ExtractNum(1, startPoint, expression);
  96.                     return Exchange(startPoint - ExtractNum(-1, startPoint, expression).ToString().Length, startPoint + ExtractNum(1, startPoint, expression).ToString().Length + 1, result.ToString(), expression);
  97.                 }
  98.  
  99.             case '*':
  100.                 {
  101.                     result = ExtractNum(-1, startPoint, expression) * ExtractNum(1, startPoint, expression);
  102.                     return Exchange(startPoint - ExtractNum(-1, startPoint, expression).ToString().Length, startPoint + ExtractNum(1, startPoint, expression).ToString().Length + 1, result.ToString(), expression);
  103.                 }
  104.  
  105.             default:
  106.                 {
  107.                     result = ExtractNum(-1, startPoint, expression) / ExtractNum(1, startPoint, expression);
  108.                     return Exchange(startPoint - ExtractNum(-1, startPoint, expression).ToString().Length, startPoint + ExtractNum(1, startPoint, expression).ToString().Length + 1, result.ToString(), expression);
  109.                 }
  110.         }
  111.     }
  112.  
  113.     private static StringBuilder Exchange(int startIndex, int endIndex, string valueToExchange, StringBuilder expression)
  114.     {
  115.         expression.Remove(startIndex, endIndex - startIndex);
  116.         expression.Insert(startIndex, valueToExchange);
  117.         return expression;
  118.     }
  119.  
  120.     private static StringBuilder CalculateFunc(int startIndex, StringBuilder expression)
  121.     {
  122.         CalculateExpression(false, startIndex, expression);
  123.         decimal result = 0;
  124.         switch (expression[startIndex - 1])
  125.         {
  126.             case 'n':
  127.                 {
  128.                     result = (decimal)Math.Log((double)ExtractNum(1, startIndex, expression));
  129.                     return Exchange(startIndex - 2, startIndex + ExtractNum(1, startIndex, expression).ToString().Length + 2, result.ToString(), expression);
  130.                 }
  131.  
  132.             case 't':
  133.                 {
  134.                     result = (decimal)Math.Sqrt((double)ExtractNum(1, startIndex, expression));
  135.                     return Exchange(startIndex - 4, startIndex + ExtractNum(1, startIndex, expression).ToString().Length + 2, result.ToString(), expression);
  136.                 }
  137.  
  138.             default:
  139.                 {
  140.                     int startIndex2 = startIndex;
  141.                     while (expression[startIndex2] != ',')
  142.                     {
  143.                         startIndex2++;
  144.                     }
  145.  
  146.                     result = (decimal)Math.Pow((double)ExtractNum(-1, startIndex2, expression), (double)ExtractNum(1, startIndex2, expression));
  147.                     return Exchange(startIndex - 3, startIndex + ExtractNum(-1, startIndex2, expression).ToString().Length + ExtractNum(1, startIndex2, expression).ToString().Length + 3, result.ToString(), expression);
  148.                 }
  149.         }
  150.     }
  151.  
  152.     private static int SearchBrackets(StringBuilder expression)
  153.     {
  154.         int index = 0;
  155.         int result = 0;
  156.         while (index < expression.Length && expression[index] != ')')
  157.         {
  158.             if (expression[index] == '(')
  159.             {
  160.                 result = index;
  161.             }
  162.  
  163.             index++;
  164.         }
  165.  
  166.         return result;
  167.     }
  168.  
  169.     private static StringBuilder CalculateExpression(bool checkForFunc, int startIndex, StringBuilder expression)
  170.     {
  171.         if (checkForFunc)
  172.         {
  173.             int mod = 1;
  174.             if (startIndex == 0)
  175.             {
  176.                 mod = 0;
  177.             }
  178.  
  179.             if (expression[startIndex - mod] == 'n' || expression[startIndex - mod] == 't' || expression[startIndex - mod] == 'w')
  180.             {
  181.                 return CalculateFunc(startIndex, expression);
  182.             }
  183.         }
  184.  
  185.         while (SearchSign('*', startIndex, expression) != 0)
  186.         {
  187.             expression = Calculate(SearchSign('*', startIndex, expression), expression);
  188.         }
  189.  
  190.         while (SearchSign('/', startIndex, expression) != 0)
  191.         {
  192.             expression = Calculate(SearchSign('/', startIndex, expression), expression);
  193.         }
  194.  
  195.         while (SearchSign('-', startIndex, expression) != 0 || SearchSign('+', startIndex, expression) != 0)
  196.         {
  197.             while (SearchSign('+', startIndex, expression) != 0)
  198.             {
  199.                 if (SearchSign('-', startIndex, expression) != 0 && (SearchSign('-', startIndex, expression) < SearchSign('+', startIndex, expression)))
  200.                 {
  201.                     break;
  202.                 }
  203.  
  204.                 expression = Calculate(SearchSign('+', startIndex, expression), expression);
  205.             }
  206.  
  207.             while (SearchSign('-', startIndex, expression) != 0)
  208.             {
  209.                 expression = Calculate(SearchSign('-', startIndex, expression), expression);
  210.             }
  211.         }
  212.  
  213.         if (checkForFunc)
  214.         {
  215.             expression.Remove(startIndex, 1);
  216.             while (expression[startIndex] != ')')
  217.             {
  218.                 startIndex++;
  219.             }
  220.  
  221.             expression.Remove(startIndex, 1);
  222.         }
  223.        
  224.         return expression;
  225.     }
  226.  
  227.     private static int SearchSign(char sign, int startIndex, StringBuilder expression)
  228.     {
  229.         int resultIndex = 0;
  230.         while (expression[startIndex] != ')' && startIndex < expression.Length)
  231.         {
  232.             bool check = expression[startIndex - 1] == '*' || expression[startIndex - 1] == '/' || expression[startIndex - 1] == '+' || expression[startIndex - 1] == '-' || expression[startIndex - 1] == ',' || expression[startIndex - 1] == '(';
  233.             if (expression[startIndex] == sign &&  !check)
  234.             {
  235.                 resultIndex = startIndex;
  236.                 break;
  237.             }
  238.  
  239.             startIndex++;
  240.         }
  241.  
  242.         return resultIndex;
  243.     }
  244. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement