Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- //Write a program that calculates the value of given arithmetical expression. The expression can contain the following elements only:
- //Real numbers, e.g. 5, 18.33, 3.14159, 12.6
- //Arithmetic operators: +, -, *, / (standard priorities)
- //Mathematical functions: ln(x), sqrt(x), pow(x,y)
- //Brackets (for changing the default priorities)
- // Examples:
- // (3+5.3) * 2.7 - ln(22) / pow(2.2, -1.7) = ~ 10.6
- // pow(2, 3.14) * (3 - (3 * sqrt(2) - 3.2) + 1.5*0.3) = ~ 21.22
- // Hint: Use the classical "shunting yard" algorithm and "reverse Polish notation".
- class ArithmeticalExpression
- {
- static Dictionary<string, int> precendce = new Dictionary<string, int>() { { "*", 2 }, { "/", 2 }, { "+", 1 }, { "-", 1 }, { "(", 5 }, { ")", 0 } };
- static void Main()
- {
- //string input = "5,4567+4*-8.2345*(2+3)";
- string input = "((2 +3 )*(4+3))*5*(2+3)*pow(2,3)/sqrt(4)";
- StringBuilder builder = new StringBuilder();
- foreach (char item in input) //clear spaces
- {
- if (item != ' ')
- {
- builder.Append(item);
- }
- }
- input = builder.ToString();
- List<Tuple<string,string>> token = new List<Tuple<string,string>>();
- StringToList(input, token);
- List<string> result = new List<string>();
- ReversePolishNotation(result, token);
- CalcResult(result);
- //print
- Console.WriteLine(result[0]);
- }
- private static void CalcResult(List<string> result)
- {
- double? first;
- double? second;
- string action;
- while (result.Count>1)
- {
- first = null;
- second = null;
- action = "";
- for (int i = 0; i < result.Count; i++)
- {
- if (!first.HasValue)
- {
- if (!precendce.ContainsKey(result[i]))
- {
- first = double.Parse(result[i]);
- }
- else
- {
- i = result.Count;
- continue;
- }
- }
- else if (!second.HasValue)
- {
- if (!precendce.ContainsKey(result[i]))
- {
- second = double.Parse(result[i]);
- }
- else
- {
- i = result.Count;
- continue;
- }
- continue;
- }
- if (first.HasValue && second.HasValue)
- {
- if (precendce.ContainsKey(result[i]))
- {
- action = result[i];
- result[i-2] = Calculate(first, second, action);
- result.Remove(result[i-1]);
- result.Remove(result[i-1]);
- i = result.Count; //exit loop
- }
- else
- {
- first = double.Parse(result[i-1]);
- second = double.Parse(result[i]); ;
- }
- }
- }
- }
- }
- private static string Calculate(double? first, double? second, string action)
- {
- switch (action)
- {
- case "+": return ((double)(first + second)).ToString();
- case "-": return ((double)(first - second)).ToString();
- case "*": return ((double)(first * second)).ToString();
- case "/": return ((double)(first / second)).ToString();
- }
- return "0";
- }
- private static void ReversePolishNotation(List<string> result, List<Tuple<string, string>> token) //Under construction
- {
- Queue<string> queue = new Queue<string>();
- Stack<string> stack = new Stack<string>();
- for (int i = 0; i < token.Count; i++)
- {
- if (token[i].Item1 == "(")
- {
- stack.Push(token[i].Item1);
- }
- if (token[i].Item1 == ")")
- {
- while (stack.Peek() != "(")
- {
- queue.Enqueue(stack.Pop());
- }
- stack.Pop();
- }
- if (token[i].Item2 == "digit")
- {
- queue.Enqueue(token[i].Item1);
- }
- else if (token[i].Item2 == "operator")
- {
- if (stack.Count > 0 && precendce[stack.Peek()] >= precendce[token[i].Item1] && stack.Peek() != "(")
- {
- queue.Enqueue(stack.Pop());
- stack.Push(token[i].Item1);
- }
- else
- {
- stack.Push(token[i].Item1);
- }
- }
- }
- //fill result in list
- int count = stack.Count;
- for (int i = 0; i < count; i++)
- {
- queue.Enqueue(stack.Pop());
- }
- count = queue.Count;
- for (int i = 0; i < count; i++)
- {
- result.Add(queue.Dequeue());
- }
- //print
- foreach (var item in result)
- {
- Console.Write(item);
- }
- }
- private static void StringToList(string input, List<Tuple<string, string>> token)
- {
- StringBuilder builder = new StringBuilder();
- string lastType = "";
- string func = "";
- string funcX = "0";
- string funcY = "0";
- for (int i = 0; i < input.Length; i++)
- {
- if (input[i] == 'l' || input[i] == 's' || input[i] == 'p' || lastType == "function") //function
- {
- if (lastType != "function")
- {
- func = input[i].ToString();
- }
- if (input[i] >= '0' && input[i] <= '9') //is digit
- {
- builder.Append(input[i]);
- }
- if (input[i] == ',')
- {
- funcX = builder.ToString();
- builder.Clear();
- }
- lastType = "function";
- if (input[i] == ')')
- {
- funcY = builder.ToString();
- builder.Clear();
- lastType = "";
- token.Add(new Tuple<string, string>(CalculateFunction(func, funcX, funcY), "digit"));
- Console.WriteLine(CalculateFunction(func, funcX, funcY));
- Console.ReadLine();
- continue;
- }
- continue;
- }
- else if ((input[i] >= '0' && input[i] <= '9') || input[i] == '.') //digit
- {
- builder.Append(input[i]);
- if (i + 1 == input.Length || (input[i + 1] < '0' && input[i + 1] != '.' && input[i + 1] != ','))
- {
- token.Add(new Tuple<string, string>(builder.ToString(), "digit"));
- builder.Clear();
- }
- lastType = "digit";
- }
- if (input[i] == '+' || input[i] == '-' || input[i] == '*' || input[i] == '/') // operator
- {
- if ((input[i] == '-' && i == 0) || (input[i] == '-' && lastType == "operator")) //case of negative
- {
- builder.Append(input[i]);
- lastType = "digit";
- continue;
- }
- builder.Append(input[i]);
- token.Add(new Tuple<string, string>(builder.ToString(), "operator"));
- lastType = "operator";
- builder.Clear();
- }
- if (input[i] == '(' || input[i] == ')') //braces
- {
- builder.Append(input[i]);
- token.Add(new Tuple<string, string>(builder.ToString(), "brace"));
- lastType = "brace";
- builder.Clear();
- }
- }
- }
- private static string CalculateFunction(string func, string funcX, string funcY)
- {
- switch (func)
- {
- case "l": return (Math.Log(double.Parse(funcY)).ToString());
- case "s": return (Math.Sqrt(double.Parse(funcY)).ToString());
- case "p": return (Math.Pow(double.Parse(funcX),double.Parse(funcY)).ToString());
- }
- return "";
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement