Advertisement
sashomaga

Arithmetical expression

Jan 20th, 2013
42
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.85 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. //Write a program that calculates the value of given arithmetical expression. The expression can contain the following elements only:
  6. //Real numbers, e.g. 5, 18.33, 3.14159, 12.6
  7. //Arithmetic operators: +, -, *, / (standard priorities)
  8. //Mathematical functions: ln(x), sqrt(x), pow(x,y)
  9. //Brackets (for changing the default priorities)
  10. //    Examples:
  11. //    (3+5.3) * 2.7 - ln(22) / pow(2.2, -1.7) = ~ 10.6
  12. //    pow(2, 3.14) * (3 - (3 * sqrt(2) - 3.2) + 1.5*0.3) = ~ 21.22
  13. //    Hint: Use the classical "shunting yard" algorithm and "reverse Polish notation".
  14.  
  15.  
  16. class ArithmeticalExpression
  17. {
  18.     static Dictionary<string, int> precendce = new Dictionary<string, int>() { { "*", 2 }, { "/", 2 }, { "+", 1 }, { "-", 1 }, { "(", 5 }, { ")", 0 } };
  19.  
  20.     static void Main()
  21.     {
  22.         //string input = "5,4567+4*-8.2345*(2+3)";
  23.         string input = "((2 +3 )*(4+3))*5*(2+3)*pow(2,3)/sqrt(4)";
  24.         StringBuilder builder = new StringBuilder();
  25.         foreach (char item in input) //clear spaces
  26.         {
  27.             if (item != ' ')
  28.             {
  29.                 builder.Append(item);
  30.             }
  31.         }
  32.         input = builder.ToString();
  33.  
  34.         List<Tuple<string,string>> token = new List<Tuple<string,string>>();
  35.         StringToList(input, token);
  36.  
  37.         List<string> result = new List<string>();
  38.         ReversePolishNotation(result, token);
  39.         CalcResult(result);
  40.         //print
  41.         Console.WriteLine(result[0]);
  42.     }
  43.  
  44.     private static void CalcResult(List<string> result)
  45.     {
  46.        
  47.         double? first;
  48.         double? second;
  49.         string action;      
  50.         while (result.Count>1)
  51.         {
  52.             first = null;
  53.             second = null;
  54.             action = "";
  55.            
  56.             for (int i = 0; i < result.Count; i++)
  57.             {
  58.                 if (!first.HasValue)
  59.                 {
  60.                     if (!precendce.ContainsKey(result[i]))
  61.                     {
  62.                         first = double.Parse(result[i]);
  63.                     }
  64.                     else
  65.                     {
  66.                         i = result.Count;
  67.                         continue;
  68.                     }
  69.                    
  70.                 }
  71.                 else if (!second.HasValue)
  72.                 {
  73.                     if (!precendce.ContainsKey(result[i]))
  74.                     {
  75.                         second = double.Parse(result[i]);
  76.                     }
  77.                     else
  78.                     {
  79.                         i = result.Count;
  80.                         continue;
  81.                     }
  82.                     continue;
  83.                 }
  84.  
  85.                 if (first.HasValue && second.HasValue)
  86.                 {
  87.                     if (precendce.ContainsKey(result[i]))
  88.                     {
  89.                         action = result[i];
  90.                         result[i-2] = Calculate(first, second, action);
  91.                         result.Remove(result[i-1]);
  92.                         result.Remove(result[i-1]);
  93.                         i = result.Count; //exit loop                                            
  94.                     }
  95.                     else
  96.                     {
  97.                         first = double.Parse(result[i-1]);
  98.                         second = double.Parse(result[i]); ;
  99.                     }
  100.                 }
  101.  
  102.             }
  103.         }
  104.        
  105.     }
  106.  
  107.     private static string Calculate(double? first, double? second, string action)
  108.     {
  109.         switch (action)
  110.         {
  111.             case "+": return ((double)(first + second)).ToString();
  112.             case "-": return ((double)(first - second)).ToString();
  113.             case "*": return ((double)(first * second)).ToString();
  114.             case "/": return ((double)(first / second)).ToString();    
  115.         }
  116.         return "0";
  117.     }
  118.  
  119.     private static void ReversePolishNotation(List<string> result, List<Tuple<string, string>> token) //Under construction
  120.     {
  121.         Queue<string> queue = new Queue<string>();
  122.         Stack<string> stack = new Stack<string>();
  123.  
  124.         for (int i = 0; i < token.Count; i++)
  125.         {
  126.             if (token[i].Item1 == "(")
  127.             {
  128.                stack.Push(token[i].Item1);
  129.             }
  130.             if (token[i].Item1 == ")")
  131.             {
  132.                 while (stack.Peek() != "(")
  133.                 {                    
  134.                     queue.Enqueue(stack.Pop());
  135.                 }
  136.                 stack.Pop();
  137.             }
  138.             if (token[i].Item2 == "digit")
  139.             {
  140.                 queue.Enqueue(token[i].Item1);
  141.             }
  142.             else if (token[i].Item2 == "operator")
  143.             {
  144.                 if (stack.Count > 0 && precendce[stack.Peek()] >= precendce[token[i].Item1] && stack.Peek() != "(")
  145.                 {
  146.                     queue.Enqueue(stack.Pop());
  147.                     stack.Push(token[i].Item1);
  148.                 }
  149.                 else
  150.                 {
  151.                     stack.Push(token[i].Item1);
  152.                 }
  153.                
  154.             }
  155.         }
  156.         //fill result in list
  157.         int count = stack.Count;
  158.         for (int i = 0; i < count; i++)
  159.         {          
  160.             queue.Enqueue(stack.Pop());
  161.         }
  162.         count = queue.Count;
  163.         for (int i = 0; i < count; i++)
  164.         {
  165.             result.Add(queue.Dequeue());
  166.         }
  167.         //print
  168.         foreach (var item in result)
  169.         {
  170.             Console.Write(item);
  171.         }
  172.  
  173.        
  174.     }
  175.  
  176.     private static void StringToList(string input, List<Tuple<string, string>> token)
  177.     {
  178.         StringBuilder builder = new StringBuilder();
  179.  
  180.         string lastType = "";
  181.         string func = "";
  182.         string funcX = "0";
  183.         string funcY = "0";
  184.         for (int i = 0; i < input.Length; i++)
  185.         {
  186.             if (input[i] == 'l' || input[i] == 's' || input[i] == 'p' || lastType == "function") //function
  187.             {
  188.                 if (lastType != "function")
  189.                 {
  190.                     func = input[i].ToString();
  191.                 }
  192.                 if (input[i] >= '0' && input[i] <= '9') //is digit
  193.                 {
  194.                     builder.Append(input[i]);
  195.                 }
  196.                 if (input[i] == ',')
  197.                 {
  198.                     funcX = builder.ToString();
  199.                     builder.Clear();
  200.                 }
  201.                 lastType = "function";
  202.  
  203.                 if (input[i] == ')')
  204.                 {
  205.                     funcY = builder.ToString();
  206.                     builder.Clear();
  207.                     lastType = "";                    
  208.                     token.Add(new Tuple<string, string>(CalculateFunction(func, funcX, funcY), "digit"));
  209.                     Console.WriteLine(CalculateFunction(func, funcX, funcY));
  210.                     Console.ReadLine();
  211.                     continue;
  212.                 }
  213.                 continue;
  214.             }
  215.             else if ((input[i] >= '0' && input[i] <= '9') || input[i] == '.') //digit
  216.             {                                                                
  217.                 builder.Append(input[i]);                
  218.  
  219.                 if (i + 1 == input.Length || (input[i + 1] < '0' && input[i + 1] != '.' && input[i + 1] != ','))
  220.                 {
  221.                     token.Add(new Tuple<string, string>(builder.ToString(), "digit"));
  222.                     builder.Clear();
  223.                 }
  224.                 lastType = "digit";
  225.             }
  226.             if (input[i] == '+' || input[i] == '-' || input[i] == '*' || input[i] == '/') // operator
  227.             {
  228.                 if ((input[i] == '-' && i == 0) || (input[i] == '-' && lastType == "operator")) //case of negative
  229.                 {
  230.                     builder.Append(input[i]);
  231.                     lastType = "digit";
  232.                     continue;
  233.                 }
  234.  
  235.                 builder.Append(input[i]);
  236.                 token.Add(new Tuple<string, string>(builder.ToString(), "operator"));
  237.                 lastType = "operator";
  238.                 builder.Clear();
  239.             }
  240.             if (input[i] == '(' || input[i] == ')') //braces
  241.             {
  242.                 builder.Append(input[i]);
  243.                 token.Add(new Tuple<string, string>(builder.ToString(), "brace"));
  244.                 lastType = "brace";
  245.                 builder.Clear();
  246.             }
  247.         }      
  248.     }
  249.  
  250.     private static string CalculateFunction(string func, string funcX, string funcY)
  251.     {
  252.         switch (func)
  253.         {
  254.             case "l": return (Math.Log(double.Parse(funcY)).ToString());
  255.             case "s": return (Math.Sqrt(double.Parse(funcY)).ToString());
  256.             case "p": return (Math.Pow(double.Parse(funcX),double.Parse(funcY)).ToString());
  257.         }
  258.         return "";
  259.     }
  260. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement