Advertisement
Guest User

ArithmeticalExpression

a guest
Aug 13th, 2013
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 11.11 KB | None | 0 0
  1. //Task7*: Write a program that calculates the value of given arithmetical expression.
  2. //        The expression can contain the following elements only:
  3. //        Real numbers, e.g. 5, 18.33, 3.14159, 12.6
  4. //        Arithmetic operators: +, -, *, / (standard priorities)
  5. //        Mathematical functions: ln(x), sqrt(x), pow(x,y)
  6. //        Brackets (for changing the default priorities)
  7. //        Examples:
  8. //              (3+5.3) * 2.7 - ln(22) / pow(2.2, -1.7) → ~ 10.6
  9. //              pow(2, 3.14) * (3 - (3 * sqrt(2) - 3.2) + 1.5*0.3) → ~ 21.22
  10. //        Hint: Use the classical "shunting yard" algorithm and "reverse Polish notation"
  11.  
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Threading;
  15.  
  16. class ArithmeticalExpression
  17. {
  18.     static bool isFunction = false;
  19.     static char[] Operators = { '*', '/', '+', '-' };
  20.  
  21.     static void Main()
  22.     {
  23.         Console.WriteLine("Please, write some arithmetical expression: ");
  24.         Examples(1, "3/(1.2*5) - pow(3/8.9E-3 +ln(7/sqrt(12-2.3/4)), sqrt(25/4))*2 - 12");
  25.         Examples(2, "1/cos(45*4) -tan(7-(3.1*7/sin(12-2.3/4)))/ sqrt(3/4.5-1.2)");
  26.         Examples(3, "2*(3+(2-(7+(3/sqrt(9*(2+(7/(3*(sin(9*(3-(4/(3-4)))))))))))))-cot(-45)");
  27.         Examples(4, "cot(sin(tan(ln(cos(sqrt(pow(sin(tan(ln(1))),1)))))))");
  28.         Console.ForegroundColor = ConsoleColor.Yellow;
  29.         Console.Write("\n x = ");
  30.         string E = Console.ReadLine();                      // reads some arithmetical expression
  31.         Console.ResetColor();
  32.  
  33.         E = E.Replace(" ", "").Replace(',', '_');           //  removes the all empty intervals and replace ',' with '_'
  34.         E = E.Replace("sin", "v").Replace("cos", "x").Replace("tan", "y").Replace("cot", "z");
  35.  
  36.         string check = "";
  37.         while (E != check)                                  // it will finish when the result is a number
  38.         {
  39.             check = E;
  40.             foreach (var item in Operators)                 // checks for each one operator
  41.             {
  42.                 E = BasicArithmeticOperations(E, item);     // calculates *, /, + or -
  43.                 for (int i = 0; i < E.Length; i++)          // removes the brackets ( )
  44.                 {
  45.                     E = PowFunction(E);                     // calculates the Square function
  46.                     isFunction = false;
  47.                     if (E[i] == '(')                        // if the bracket is open
  48.                     {
  49.                         if (i > 0)
  50.                         {
  51.                             E = Functions(E, i, 'n');       // calculates the Natural logarithm function
  52.                             E = Functions(E, i, 't');       // calculates the Square root function
  53.                             E = Functions(E, i, 'v');       // calculates the Sinus function
  54.                             E = Functions(E, i, 'x');       // calculates the Cosinus function
  55.                             E = Functions(E, i, 'y');       // calculates the Tangens function
  56.                             E = Functions(E, i, 'z');       // calculates the Cotangens function
  57.                         }
  58.                         if (!isFunction)                    // if Ln or Sqrt are used
  59.                         {
  60.                             E = BracketsPriority(E, i);
  61.                         }
  62.                     }
  63.                 }
  64.             }
  65.         }
  66.  
  67.         Console.Write("\n x = ");
  68.         E = E.Contains("NaN") ? "NaN" : E;                  // checks for NaN
  69.         double R = 0;
  70.         if (double.TryParse(E, out R))
  71.         {
  72.             Console.ForegroundColor = ConsoleColor.Green;
  73.             Console.WriteLine(R.ToString("E2"));            // prints the result
  74.         }
  75.         else
  76.         {
  77.             Console.ForegroundColor = ConsoleColor.Red;
  78.             Console.WriteLine("Wrong expression!");         // if there is some error in expression
  79.         }
  80.         Console.ResetColor();
  81.     }
  82.  
  83.     static void Examples(int n, string s)
  84.     {
  85.         Console.Write("Example{0}: ", n);
  86.         Console.ForegroundColor = ConsoleColor.Magenta;
  87.         Console.WriteLine(s);
  88.         Console.ResetColor();
  89.     }
  90.  
  91.     static string BracketsPriority(string E, int i)
  92.     {
  93.         double num = 0;
  94.         string temp = "";
  95.         for (int j = i + 1; j < E.Length; j++)
  96.         {
  97.             temp += E[j];
  98.  
  99.             /* calculates the expression in the brackets */
  100.             if (double.TryParse(temp, out num) && E[j + 1] == ')')
  101.             {
  102.                 E = (E.Remove(i, 1)).Remove(j, 1);
  103.                 E = TempResult(E);
  104.                 break;
  105.             }
  106.         }
  107.         return E;
  108.     }
  109.  
  110.     static string PowFunction(string E)
  111.     {
  112.         E = E.Replace("_+", "_");                           // replaces the "_+" with "_"
  113.         for (int p = 0; p < E.Length; p++)
  114.         {
  115.             if (E[p] == '_')                                // looking for position of "_" (",")
  116.             {
  117.                 bool available1, available2;                // are there two numbers in Pow function
  118.                 int before, after;                          // the positions before and after the "_" symbol
  119.                 double num1 = SearchNumber(E, p, out available1, out before, 0, p);
  120.                 double num2 = SearchNumber(E, p, out available2, out after, p + 1, E.Length);
  121.                 if (available1 && available2 && E[before - 1] == '(' && E[E.Length + p - after + 1] == ')')
  122.                 {
  123.                     double result = Math.Pow(num1, num2);
  124.                     E = (E.Remove(before - 4, E.Length + p - after - before + 6)).Insert(before - 4, result.ToString());
  125.                     p = 0;
  126.                     E = TempResult(E);
  127.                 }
  128.             }
  129.         }
  130.         return E;                                           // returns the calculated Pow function
  131.     }
  132.  
  133.     static string Functions(string E, int i, char f)
  134.     {
  135.         if (!isFunction)
  136.         {
  137.             if (E[i - 1] == f)                                  // what is this function
  138.             {
  139.                 byte word_len = 0;                              // the length of the function word
  140.                 double num = 0;
  141.                 string temp = "";
  142.                 for (int j = i + 1; j < E.Length; j++)
  143.                 {
  144.                     temp += E[j];
  145.                     if (double.TryParse(temp, out num) && E[j + 1] == ')')
  146.                     {
  147.                         /* calculates the expression in the brackets for the respective function*/
  148.                         double result = 0;
  149.                         switch (f)
  150.                         {
  151.                             case 'n': result = Math.Log(num); word_len = 2; break;
  152.                             case 't': result = Math.Sqrt(num); word_len = 4; break;
  153.                             case 'v': result = Math.Sin(num * Math.PI / 180); word_len = 1; break;
  154.                             case 'x': result = Math.Cos(num * Math.PI / 180); word_len = 1; break;
  155.                             case 'y': result = Math.Tan(num * Math.PI / 180); word_len = 1; break;
  156.                             case 'z': result = 1 / Math.Tan(num * Math.PI / 180); word_len = 1; break;
  157.                             default: break;
  158.                         }
  159.                         E = (E.Remove(i - word_len, j - i + word_len + 2)).Insert(i - word_len, result.ToString());
  160.                         E = TempResult(E);
  161.                         isFunction = true;                  // some function is used
  162.                         break;
  163.                     }
  164.                 }
  165.             }
  166.         }
  167.         return E;                                           // returns the result from this function
  168.     }
  169.  
  170.     static string BasicArithmeticOperations(string E, char symbol)
  171.     {
  172.         for (int i = 0; i < E.Length; i++)
  173.         {
  174.             if (E[i] == symbol)                             // looking for position of *, /, + or -
  175.             {
  176.                 bool available1, available2;
  177.                 int before, after;
  178.                 double num1 = SearchNumber(E, i, out available1, out before, 0, i);
  179.                 double num2 = SearchNumber(E, i, out available2, out after, i + 1, E.Length);
  180.  
  181.                 double result = 0;
  182.                 switch (symbol)
  183.                 {
  184.                     case '*': result = num1 * num2; break;
  185.                     case '/': result = num1 / num2; break;
  186.                     case '+': result = num1 + num2; break;
  187.                     case '-': result = num1 - num2; break;
  188.                     default: break;
  189.                 }
  190.  
  191.                 /* calculates the expression from *, /, + or - operators */
  192.                 if (available1 && available2)
  193.                 {
  194.                     string sign = "";
  195.                     sign = result > 0 || result.ToString().Contains("NaN") ? "+" + result.ToString() : result.ToString();
  196.                     E = (E.Remove(before, E.Length + i - after - before + 1)).Insert(before, sign);
  197.                     i = 0;
  198.                     E = TempResult(E);
  199.                 }
  200.             }
  201.         }
  202.         return E;                                           // returns the result from calculations
  203.     }
  204.  
  205.     static double SearchNumber(string E, int i, out bool available, out int limit, int start, int end)
  206.     {
  207.         available = false;                                  // is there some number
  208.         double num = 0;                                     // the value of the number
  209.         limit = 0;                                          // the length of the number
  210.         for (limit = start; limit < end; limit++)
  211.         {
  212.             int k = start == 0 ? limit : start;
  213.  
  214.             if (double.TryParse(E.Substring(k, end - limit), out num))
  215.             {
  216.                 available = true;                           // if the number is found
  217.                 if (E[i] == '+' || E[i] == '-')             // checks the priority of '*' and '/'
  218.                 {
  219.                     if (i - (end - limit + 1) >= 0 && start < i)
  220.                     {
  221.                         if (E[i - (end - limit + 1)] == '*' || E[i - (end - limit + 1)] == '/')
  222.                         {
  223.                             available = false;              // this number will not be used
  224.                         }
  225.                     }
  226.                     if (i + (end - limit) + 1 < E.Length && start > i)
  227.                     {
  228.                         if (E[i + (end - limit) + 1] == '*' || E[i + (end - limit) + 1] == '/')
  229.                         {
  230.                             available = false;              // this number will not be used
  231.                         }
  232.                     }
  233.                 }
  234.                 break;
  235.             }
  236.         }
  237.         return num;                                         // returns the value of the number
  238.     }
  239.  
  240.     static string TempResult(string E)
  241.     {
  242.         E = E.Replace("-+", "-");
  243.         Thread.Sleep(1000);                                 // sleep for 1 second
  244.         Console.WriteLine(" x = {0}", E.Replace('_', ',').Replace("v", "sin").Replace("x", "cos").Replace("y", "tan").Replace("z", "cot"));
  245.         return E;
  246.     }
  247. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement