Калькулятор: сделать обратную польскую запись - C#

Узнай цену своей работы

Формулировка задачи:

есть инженерный калькулятор, нужно сделать обратную польскую запись или другими словами сделать приоритетность действий...помогите пожалуйста

Решение задачи: «Калькулятор: сделать обратную польскую запись»

textual
Листинг программы
  1.         public string Create_OPZ(string input_string)
  2.         {
  3.             string[] output_string=new string[0];//выходная строка(массив)(так она называется на википедии)
  4.             string[] stack=new string[0];//стек
  5.            
  6.             int k = 0;
  7.             for (int i = 0; i < input_string.Length; i++)
  8.             {
  9.                 string temp = "";//как бы это было не удивительно, но переменная для хранения числа
  10.                 //проверка на отрицательное число: зсли знак "-" в начале строки или перед знаком "-" нет числа
  11.                 if (input_string[i] == '-' && ((i > 0 && !Char.IsDigit(input_string[i - 1])) || i == 0))
  12.                 {
  13.                     i++;
  14.                     temp += "-";//в переменную для чисел добавляется знак "-"
  15.                 }
  16.                 if (Char.IsDigit(input_string[i]))
  17.                 {                    
  18.                     //найдено число и в переменную temp записываются все цифры числа, тк число может состоять не только из одной цифры
  19.                     while (i < input_string.Length&&Char.IsDigit(input_string[i]))
  20.                         temp += input_string[i++].ToString();
  21.                     i--;
  22.                     Array.Resize(ref output_string, output_string.Length + 1);//массив выходной строки динамически увеличиваем на единицу
  23.                     output_string[output_string.Length - 1] = temp;//добавляем число в текущий элемент выходной строки
  24.                 }
  25.                 if (input_string[i] == '+' || input_string[i] == '-')
  26.                 {
  27.                 m://т.к + и - имеют самый низкий приоритет, то при записывании этих операндов в стек
  28.                     //все остальные операции из стека должны переместится в выходную строку(исключение скобка)
  29.                     if (stack.Length != 0) //если стек еще не пуст
  30.                     {
  31.                         if (stack[stack.Length - 1] == "(")//если последний элемент стека открывающаяся скобка
  32.                         {
  33.                             Array.Resize(ref stack, stack.Length + 1);
  34.                             stack[stack.Length - 1] = input_string[i].ToString();//то в стек добавляется операция сложения или отрицания
  35.                         }
  36.                         else //иначе
  37.                         {
  38.                             Array.Resize(ref output_string, output_string.Length + 1);
  39.                             output_string[output_string.Length - 1] = stack[stack.Length - 1];//в выходную строку добавляется последняя операция из стека
  40.                             Array.Resize(ref stack, stack.Length - 1);//у стека удаляется последний элемент
  41.                             goto m;//возврат на проверку находится ли на вершине стека еще какая либо операция
  42.                         }
  43.                         stack[stack.Length - 1] = input_string[i].ToString();//на вершину стека помещается операция + или -
  44.                     }
  45.                     else
  46.                     {
  47.                         Array.Resize(ref stack, stack.Length + 1);
  48.                         stack[stack.Length - 1] = input_string[i].ToString();//если стек не пуст то в стек добавляется операция сложения или отрицания
  49.                     }
  50.                 }
  51.                 if (input_string[i] == '*' || input_string[i] == '/')
  52.                 {
  53.  
  54.                     if (stack.Length != 0)//если стек еще не пуст
  55.                     {
  56.  
  57.                         if (stack[stack.Length - 1] != "*" && stack[stack.Length - 1] != "/")//если на вершине стека не располагается * или /
  58.                         {
  59.                             Array.Resize(ref stack, stack.Length + 1);
  60.                             stack[stack.Length - 1] = input_string[i].ToString();
  61.                         }
  62.                         else  //если на вершине стека располагается * или /
  63.                         {//то т.к приоритеты операций одинаковые...
  64.                             Array.Resize(ref output_string, output_string.Length + 1);
  65.                             output_string[output_string.Length - 1] = stack[stack.Length - 1];//...элемент с вершины стека передается в выходную строку(массив)
  66.                             stack[stack.Length - 1] = input_string[i].ToString();//на вершину стека становится текщая операция умножения или деления
  67.                            
  68.                         }
  69.                        
  70.                     }
  71.                     else
  72.                     {
  73.                         Array.Resize(ref stack, stack.Length + 1);
  74.                         stack[stack.Length - 1] = input_string[i].ToString();//если стек не пуст то в стек добавляется операция умножения или деления
  75.                     }
  76.                 }
  77.                 if (input_string[i] == '(')
  78.                 {//найдена открывающаяся скобка которая автоматически добавляется в стек
  79.                     Array.Resize(ref stack, stack.Length + 1);
  80.                     stack[stack.Length - 1] = input_string[i].ToString();
  81.                 }
  82.                 if (input_string[i] == ')')
  83.                 {//найдена закрывающаяся скобка
  84.                     int k_t = stack.Length - 1;
  85.                     while (stack[k_t] != "(")//некий цикл который начиная с конца стека перемещается влево в поисках открывающиейся скобки
  86.                         k_t--;//после цикла здесь хранится индекс открывающейся скобки
  87.                     int j;
  88.                     for (j = k_t+1; j < stack.Length; j++)//все операции которые хранились в стеке после "(" переносятся в выходную строку
  89.                     {
  90.                         Array.Resize(ref output_string, output_string.Length + 1);
  91.                         output_string[output_string.Length - 1] = stack[j];
  92.                     }
  93.                     Array.Resize(ref stack,stack.Length-j);//стек уменьшается на количество переданных операций
  94.                 }
  95.                 if (input_string[i] == '^')//т.к у возведения в степень самый большой приоритет, его автоматически добавляют в выходную строку
  96.                 {
  97.                     Array.Resize(ref stack, stack.Length + 1);
  98.                     stack[stack.Length - 1] = input_string[i].ToString();
  99.                 }
  100.             }
  101.             //всю ВХодную строку проверили теперь в стеке и в ВЫХодной строке содержатся некоторые данные
  102.             //объединяем выходную строку со стеком
  103.             Array.Resize(ref output_string, output_string.Length + stack.Length);
  104.             Array.Reverse(stack);//это просто что бы не парится и не создавать цкл который будет идти задом на перед
  105.             //т.к иначе есть свои нюансы в которые я вдаваться не хочу
  106.             for (int i = output_string.Length - stack.Length; i < output_string.Length;i++)
  107.                 output_string[i] = stack[k++];
  108.             string t="";//сформировали из выходной строки(массива) строку
  109.             for (int i = 0; i < output_string.Length; i++)
  110.                 if (i != output_string.Length-1)
  111.                     t += output_string[i] + " ";
  112.                 else
  113.                     t += output_string[i];
  114.             return t;//передали полученную строку
  115.         }
  116.  
  117.         public double Solution(string OPZ_String)
  118.         {
  119.             string[] mas = OPZ_String.Split(' ');//нарезаем строку в виде Обратной польской записи в массив элементов
  120.             string temp_string;
  121.             for(int i=0;i<mas.Length;i++)
  122.                 switch (mas[i])
  123.                 {
  124.                     case "+"://если найдена операция сложения
  125.                         temp_string = (double.Parse(mas[i - 2]) + double.Parse(mas[i - 1])).ToString();//выполняем сложение и переводим ее в строку
  126.                         richTextBox1.AppendText(mas[i - 2] +"+"+ mas[i - 1]+"="+temp_string+"\n");
  127.                         mas[i - 2] = temp_string;//на место 1-ого операнда записывается результат (как если бы a=a+b)
  128.                         for (int j = i - 1; j < mas.Length - 2; j++)//удаляем из массива второй операнд и знак арифм действия
  129.                             mas[j] = mas[j + 2];
  130.                         Array.Resize(ref mas,mas.Length-2);//обрезаем массив элементов на 2 удаленнх элемента
  131.                         i -= 2;
  132.                         break;
  133.                     case "-"://далее все аналогично
  134.                         temp_string = (double.Parse(mas[i - 2]) - double.Parse(mas[i - 1])).ToString();
  135.                         richTextBox1.AppendText(mas[i - 2] + "-" + mas[i - 1] + "=" + temp_string + "\n");
  136.                         mas[i - 2] = temp_string;
  137.                         for (int j = i - 1; j < mas.Length - 2; j++)
  138.                             mas[j] = mas[j + 2];
  139.                         Array.Resize(ref mas, mas.Length - 2);
  140.                         i -= 2;
  141.                         break;
  142.                     case "*":
  143.                         temp_string = (double.Parse(mas[i - 2]) * double.Parse(mas[i - 1])).ToString();
  144.                         richTextBox1.AppendText(mas[i - 2] + "*" + mas[i - 1] + "=" + temp_string + "\n");
  145.                         mas[i - 2]=temp_string;
  146.                         for (int j = i - 1; j < mas.Length - 2; j++)
  147.                             mas[j] = mas[j + 2];
  148.                         Array.Resize(ref mas, mas.Length - 2);
  149.                        
  150.                         i -= 2;
  151.                         break;
  152.                     case "/":
  153.                         temp_string = (double.Parse(mas[i - 2]) / double.Parse(mas[i - 1])).ToString();
  154.                         richTextBox1.AppendText(mas[i - 2] + "/" + mas[i - 1] + "=" + temp_string + "\n");
  155.                         mas[i - 2] = temp_string;
  156.                         for (int j = i - 1; j < mas.Length - 2; j++)
  157.                             mas[j] = mas[j + 2];
  158.                         Array.Resize(ref mas, mas.Length - 2);
  159.                         i -= 2;
  160.                         break;
  161.                     case "^":
  162.                         temp_string = (Math.Pow(double.Parse(mas[i - 2]),double.Parse(mas[i - 1]))).ToString();
  163.                         richTextBox1.AppendText(mas[i - 2] + "^" + mas[i - 1] + "=" + temp_string + "\n");
  164.                         mas[i - 2] = temp_string;
  165.                         for (int j = i - 1; j < mas.Length - 2; j++)
  166.                             mas[j] = mas[j + 2];
  167.                         Array.Resize(ref mas, mas.Length - 2);
  168.                         i -= 2;
  169.                         break;
  170.                 }
  171.             return double.Parse(mas[0]);
  172.         }
  173.  
  174.         private void button3_Click(object sender, EventArgs e)
  175.         {
  176.             double result = Solution(Create_OPZ(textBox1.Text));
  177.             this.Text ="Ответ: "+ result.ToString();            
  178.         }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

15   голосов , оценка 4.267 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы