static public string ReverseInPolishNotation(string str) { StackOfOperators top = null; string finalExpression = "", buffer; while (true) { if (str == "") { break; } buffer = MathExpression.GetMemberOfExpression(ref str);//Получаем под строку и вычитаем эту подстроку из исходной строки вместе с пробелом if (buffer == "(" || buffer == ")" || buffer == "+" || buffer == "-" || buffer == "*" || buffer == "/" || buffer == "^") { if (buffer == "(") { AddStack(ref top, '('); } else if (buffer == ")") { while (true) { if (top.data == '(') { if (top.next != null) { top = top.next; } else { top = null; } break; } finalExpression += (top.data + " "); top = top.next; } } else { int priority = GetPriority(Convert.ToChar(buffer));//Получаем приоритет текущего оператора чтобы знать какие операторы выталкивать из стека while (true) { if (top == null) { break; } else if (top.data == '(') { //top = top.next; break; } else if (top.priority > priority) { break; } finalExpression += (top.data + " "); top = top.next; } AddStack(ref top, Convert.ToChar(buffer)); } } else { double result = 0; if (buffer[0] == 's' || buffer[0] == 'c' || buffer[0] == 't') { if (buffer[0] == 's') { buffer = MathExpression.GetExpressionIn(ref str); string strForSinCosTgCtgInPolishNotation = ReverseInPolishNotation(buffer); //Записываем сьда выражение внутри sin, cos, tg или ctg с помощью обратной польской записи result = ReverseOutPolishNotation(strForSinCosTgCtgInPolishNotation); //Получаем ответ из выражение внутри sin, cos, th или ctg которое уже записанно обратной польской записью result = Math.Sin(result); } else if (buffer[0] == 'c' && buffer[1] == 'o') { buffer = MathExpression.GetExpressionIn(ref str); string strForSinCosTgCtgInPolishNotation = ReverseInPolishNotation(buffer); //Записываем сьда выражение внутри sin, cos, tg или ctg с помощью обратной польской записи result = ReverseOutPolishNotation(strForSinCosTgCtgInPolishNotation); //Получаем ответ из выражение внутри sin, cos, th или ctg которое уже записанно обратной польской записью result = Math.Cos(result); } else if (buffer[0] == 't') { buffer = MathExpression.GetExpressionIn(ref str); string strForSinCosTgCtgInPolishNotation = ReverseInPolishNotation(buffer); //Записываем сьда выражение внутри sin, cos, tg или ctg с помощью обратной польской записи result = ReverseOutPolishNotation(strForSinCosTgCtgInPolishNotation); //Получаем ответ из выражение внутри sin, cos, th или ctg которое уже записанно обратной польской записью if ((result * 100) % (3.14 * 100 / 2) <= 0.0000000001 && (result * 100) % (3.14 * 100 / 2) >= -0.0000000001) //Остаток от деления работает плохо с нецелыми числами так что мы здесь немного подшаманим { return("Недопустимое выражение в tg"); } result = Math.Tan(result); } else if (buffer[0] == 'c' && buffer[1] == 't') { buffer = MathExpression.GetExpressionIn(ref str); string strForSinCosTgCtgInPolishNotation = ReverseInPolishNotation(buffer); //Записываем сьда выражение внутри sin, cos, tg или ctg с помощью обратной польской записи result = ReverseOutPolishNotation(strForSinCosTgCtgInPolishNotation); //Получаем ответ из выражение внутри sin, cos, th или ctg которое уже записанно обратной польской записью if ((result * 100) % (3.14 * 100) <= 0.0000000001 && (result * 100) % (3.14 * 100) >= -0.0000000001) { return("Недопустимое выражение в ctg"); } result = 1.0 / Math.Tan(result); } finalExpression += (Convert.ToString(result) + " "); } else if (buffer[0] == 'p') { finalExpression += ("3.14 "); } else if (buffer == "e") { finalExpression += ("2.72 "); } else { finalExpression += (buffer + " "); } } } while (top != null) { finalExpression += (top.data + " "); top = top.next; } //Console.WriteLine(finalExpression); //Console.WriteLine(str); string bf = ""; for (int i = 0; i < finalExpression.Length - 1; i++) { bf += finalExpression[i]; } finalExpression = bf; return(finalExpression); }
private void buttonEqualSign_Click(object sender, EventArgs e) { try { System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US"); double coefficient;//Коофицент растяжения if (textBoxCoefficient.Text == "") { coefficient = 1; } else { coefficient = Convert.ToDouble(textBoxCoefficient.Text); } double Xmin, Xmax;//Область определеня if (textBoxXmin.Text == "") { Xmin = 0; } else { Xmin = Convert.ToDouble(textBoxXmin.Text); } if (textBoxXmax.Text == "") { Xmax = 900; } else { Xmax = Convert.ToDouble(textBoxXmax.Text); } double coefficientX = Math.Abs(Xmax - Xmin) / 900.0;//Ширина pictureBox = 900, расчитываем шаг по значения (1 пиксель = coefficientX) if (Xmax <= Xmin) { return; } //Проверяем есть ли Х в выражении bool haveX = false; for (int i = 0; arr[i] != 0; i++) { if (arr[i] == 'x') { haveX = true; break; } } if (haveX == false) { for (int i = 0; arr[i] != 0; i++) { arr[i] = (char)0; } position = 0; label1.Text = "Ошибка! Отсутствует x"; return; } //Заменяем ÷ на / for (int i = 0; arr[i] != 0; i++) { if (arr[i] == '÷') { arr[i] = '/'; } } //Проверяем выражение на корректность string str = ""; for (int i = 0; arr[i] != 0; i++) { str += arr[i]; } str = MathExpression.ReplaceX(str, 1 - 450); str = MathExpression.NormExpression(str); if (str == "Ты ввёл некорректное выражение!") { label1.Text = "Некорректное выражение!"; return; } /////////////////////////////////////////////////////////////////////////////////////////////////////////// Graphics graphics = pictureBox1.CreateGraphics(); Pen pen = new Pen(Color.Black, 3f); Point[] points = new Point[900]; //Формируем массив точек и рисуем граффик по ним double x = Xmin;//Начинаем осчёт с крайнего левого значения for (int i = 0; i < points.Length; i++) { //Копируем символы из массива в строку str = ""; for (int j = 0; arr[j] != 0; j++) { str += arr[j]; } str = MathExpression.ReplaceX(str, x); str = MathExpression.NormExpression(str); str = Calculator.ReverseInPolishNotation(str); if (str == "Недопустимое выражение в tg") { continue; } else if (str == "Недопустимое выражение в ctg") { continue; } double result = Calculator.ReverseOutPolishNotation(str); points[i] = new Point(i, 275 - (int)(result * coefficient)); //275 - это центральная ось(y = 0), coefficient указывает на то как сильно бы толжны растянуть x += coefficientX; //Делаем шаг //граффик вдоль оси Oy } try { DrawDivisionPriceX(textBoxDivisionPriceX.Text.Length == 0 ? 1 : Convert.ToDouble(textBoxDivisionPriceX.Text), textBoxDivisionPriceY.Text.Length == 0 ? Math.Round((275 / coefficient / 5), 2) : Convert.ToDouble(textBoxDivisionPriceY.Text), coefficient, Xmin, Xmax, pictureBox1);//Оисем рисочки цены деления и ось Oy если она есть на области определения DrawHorizontLine(pictureBox1); graphics.DrawLines(pen, points);//Рисуем граффик } catch { } } catch { } }
static public double ReverseOutPolishNotation(string str) { System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US"); StackOfDouble top = null; string buffer; while (str != "") { buffer = MathExpression.GetMemberOfExpression(ref str); if (buffer != "+" && buffer != "-" && buffer != "*" && buffer != "/" && buffer != "^") { double data = Convert.ToDouble(buffer); AddStack(ref top, data); } else { if (buffer == "+") { double num1, num2; num1 = top.data; top = top.next; num2 = top.data; top = top.next; AddStack(ref top, num2 + num1); } else if (buffer == "-") { double num1, num2; num1 = top.data; top = top.next; num2 = top.data; top = top.next; AddStack(ref top, num2 - num1); } else if (buffer == "*") { double num1, num2; num1 = top.data; top = top.next; num2 = top.data; top = top.next; AddStack(ref top, num2 * num1); } else if (buffer == "/") { double num1, num2; num1 = top.data; top = top.next; num2 = top.data; top = top.next; AddStack(ref top, num2 / num1); } else if (buffer == "^") { double num1, num2; num1 = top.data; top = top.next; num2 = top.data; top = top.next; AddStack(ref top, Math.Pow(num2, num1)); } } } return(top.data); }