Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Globalization;
- using System.Collections.Generic;
- using System.Linq;
- class Program
- {
- private static readonly CultureInfo Culture = new CultureInfo("pl-PL");
- static List<string> Tokenize(string expression, Dictionary<string, int> opMap, List<string> functions, Dictionary<string, double> constants)
- {
- List<string> tokens = new List<string>();
- string temp = "";
- for (int i = 0; i < expression.Length; ++i)
- {
- char c = expression[i];
- if (c == ' ') continue;
- // Obsługa stałych matematycznych
- if (char.IsLetter(c) && constants.ContainsKey(c.ToString()))
- {
- if (!string.IsNullOrEmpty(temp))
- {
- tokens.Add(temp);
- temp = "";
- }
- tokens.Add(c.ToString());
- continue;
- }
- // Obsługa przecinków w funkcjach wieloargumentowych
- if (c == ',')
- {
- if (!string.IsNullOrEmpty(temp))
- {
- tokens.Add(temp);
- temp = "";
- }
- tokens.Add(",");
- continue;
- }
- // Sprawdź czy to funkcja
- if (char.IsLetter(c))
- {
- temp += c;
- continue;
- }
- // Obsługa operatorów
- if (opMap.ContainsKey(c.ToString()) && c != '-')
- {
- if (!string.IsNullOrEmpty(temp))
- {
- tokens.Add(temp);
- temp = "";
- }
- tokens.Add(c.ToString());
- }
- else if (c == '-')
- {
- bool isUnary = (i == 0) ||
- (i > 0 && (opMap.ContainsKey(expression[i-1].ToString()) ||
- expression[i-1] == '(' ||
- expression[i-1] == ','));
- if (!string.IsNullOrEmpty(temp) && !isUnary)
- {
- tokens.Add(temp);
- temp = "";
- tokens.Add(c.ToString());
- }
- else if (isUnary)
- {
- if (!string.IsNullOrEmpty(temp))
- {
- tokens.Add(temp);
- temp = "";
- }
- temp += c;
- }
- }
- else if (c == '(' || c == ')')
- {
- if (!string.IsNullOrEmpty(temp))
- {
- tokens.Add(temp);
- temp = "";
- }
- tokens.Add(c.ToString());
- }
- else
- {
- temp += c;
- }
- }
- if (!string.IsNullOrEmpty(temp))
- {
- tokens.Add(temp);
- }
- return tokens;
- }
- static List<string> InfixToPostfix(List<string> infix, Dictionary<string, int> opMap, List<string> functions)
- {
- List<string> postfix = new List<string>();
- Stack<string> stack = new Stack<string>();
- stack.Push("(");
- infix.Add(")");
- foreach (string token in infix)
- {
- if (!opMap.ContainsKey(token) && !functions.Contains(token) &&
- token != "(" && token != ")" && token != ",")
- {
- postfix.Add(token);
- }
- else if (token == "(")
- {
- stack.Push("(");
- }
- else if (token == ")")
- {
- while (stack.Peek() != "(")
- {
- postfix.Add(stack.Pop());
- }
- stack.Pop(); // Usuń "(" ze stosu
- // Jeśli na stosie jest funkcja
- if (stack.Count > 0 && functions.Contains(stack.Peek()))
- {
- postfix.Add(stack.Pop());
- }
- }
- else if (token == ",")
- {
- // Przetwarzaj argumenty funkcji
- while (stack.Peek() != "(")
- {
- postfix.Add(stack.Pop());
- }
- }
- else if (functions.Contains(token))
- {
- stack.Push(token);
- }
- else
- {
- while (stack.Count > 0 && opMap[token] <= opMap[stack.Peek()])
- {
- postfix.Add(stack.Pop());
- }
- stack.Push(token);
- }
- }
- return postfix;
- }
- static double CalculatePostfix(List<string> postfix, Dictionary<string, int> opMap, List<string> functions, Dictionary<string, double> constants)
- {
- Stack<double> stack = new Stack<double>();
- int argCount = 1;
- foreach (string token in postfix)
- {
- if (opMap.ContainsKey(token))
- {
- if (token == "u-")
- {
- double num = stack.Pop();
- stack.Push(-num);
- }
- else
- {
- double n1 = stack.Pop();
- double n2 = stack.Pop();
- switch (token[0])
- {
- case '+': stack.Push(n2 + n1); break;
- case '-': stack.Push(n2 - n1); break;
- case '*': stack.Push(n2 * n1); break;
- case '/': stack.Push(n2 / n1); break;
- case '^': stack.Push(Math.Pow(n2, n1)); break;
- }
- }
- argCount = 1;
- }
- else if (functions.Contains(token))
- {
- if (token == "log")
- {
- if (argCount == 1)
- {
- double x = stack.Pop();
- stack.Push(Math.Log10(x));
- }
- else if (argCount == 2)
- {
- double x = stack.Pop();
- double a = stack.Pop();
- stack.Push((double)(Math.Log(x) / Math.Log(a)));
- }
- }
- else
- {
- double num = stack.Pop();
- switch (token)
- {
- case "exp": stack.Push(Math.Exp(num)); break;
- case "ln": stack.Push(Math.Log(num)); break;
- case "sqrt": stack.Push(Math.Sqrt(num)); break;
- case "sin": stack.Push(Math.Sin(num)); break;
- case "cos": stack.Push(Math.Cos(num)); break;
- case "tan": stack.Push(Math.Tan(num)); break;
- // Funkcje cyklometryczne (odwrotne do trygonometrycznych):
- case "arcsin": stack.Push(Math.Asin(num)); break;
- case "arccos": stack.Push(Math.Acos(num)); break;
- case "arctan": stack.Push(Math.Atan(num)); break;
- case "deg2rad": stack.Push(num * (Math.PI / 180.0)); break;
- case "rad2deg": stack.Push(num * (180.0 / Math.PI)); break;
- }
- }
- argCount = 1;
- }
- else if (constants.ContainsKey(token))
- {
- stack.Push(constants[token]);
- }
- else if (token == ";")
- {
- argCount++;
- }
- else
- {
- stack.Push(double.Parse(token));
- }
- }
- return stack.Pop();
- }
- static void Main()
- {
- CultureInfo.DefaultThreadCurrentCulture = Culture;
- CultureInfo.DefaultThreadCurrentUICulture = Culture;
- Dictionary<string, int> opMap = new Dictionary<string, int>
- {
- {"^", 4},
- {"u-", 3},
- {"*", 2},
- {"/", 2},
- {"+", 1},
- {"-", 1},
- {"(", -1},
- {")", -1},
- };
- List<string> functions = new List<string> {
- "exp", "ln", "log", "sqrt",
- "sin", "cos", "tan",
- "arcsin", "arccos", "arctan", // Funkcje cyklometryczne
- "deg2rad", "rad2deg"
- };
- Dictionary<string, double> constants = new Dictionary<string, double>
- {
- {"π", Math.PI},
- {"e", Math.E},
- {"pi",Math.PI}
- };
- Console.WriteLine("Kalkulator naukowy");
- Console.WriteLine("Dostępne stałe:");
- Console.WriteLine("- π (pi) = 3.141592...");
- Console.WriteLine("- e = 2.718281...");
- Console.WriteLine("\nDostępne funkcje:");
- Console.WriteLine("- Funkcje trygonometryczne: sin(x), cos(x), tan(x)");
- Console.WriteLine("- Funkcje cyklometryczne (odwrotne do trygonometrycznych):");
- Console.WriteLine(" arcsin(x), arccos(x), arctan(x)");
- Console.WriteLine("- Konwersje: deg2rad(x), rad2deg(x)");
- Console.WriteLine("- Pierwiastki i potęgi: sqrt(x), x^y");
- Console.WriteLine("- Logarytmy: log(x), log(a,x), ln(x)");
- Console.WriteLine("- Funkcja wykładnicza: exp(x)");
- Console.WriteLine("\nPrzykłady:");
- Console.WriteLine(" arcsin(0.5) → 0.523599 rad (30°)");
- Console.WriteLine(" rad2deg(arccos(0.5)) → 60");
- Console.WriteLine(" arctan(1) → 0.785398 rad (45°)");
- Console.WriteLine(" sin(arcsin(0.8)) → 0.8");
- while (true)
- {
- Console.WriteLine("\nWprowadź wyrażenie (lub 'q' aby wyjść):");
- string expression = Console.ReadLine();
- if (expression.ToLower() == "q") break;
- try
- {
- List<string> tokens = Tokenize(expression, opMap, functions, constants);
- List<string> postfix = InfixToPostfix(tokens, opMap, functions);
- double result = CalculatePostfix(postfix, opMap, functions, constants);
- Console.WriteLine(string.Format("Wynik: {0}", result));
- }
- catch (Exception ex)
- {
- Console.WriteLine(string.Format("Błąd: {0}", ex.Message));
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment