Калькулятор: сделать обратную польскую запись - C#
Формулировка задачи:
есть инженерный калькулятор, нужно сделать обратную польскую запись или другими словами сделать приоритетность действий...помогите пожалуйста
Решение задачи: «Калькулятор: сделать обратную польскую запись»
textual
Листинг программы
public string Create_OPZ(string input_string) { string[] output_string=new string[0];//выходная строка(массив)(так она называется на википедии) string[] stack=new string[0];//стек int k = 0; for (int i = 0; i < input_string.Length; i++) { string temp = "";//как бы это было не удивительно, но переменная для хранения числа //проверка на отрицательное число: зсли знак "-" в начале строки или перед знаком "-" нет числа if (input_string[i] == '-' && ((i > 0 && !Char.IsDigit(input_string[i - 1])) || i == 0)) { i++; temp += "-";//в переменную для чисел добавляется знак "-" } if (Char.IsDigit(input_string[i])) { //найдено число и в переменную temp записываются все цифры числа, тк число может состоять не только из одной цифры while (i < input_string.Length&&Char.IsDigit(input_string[i])) temp += input_string[i++].ToString(); i--; Array.Resize(ref output_string, output_string.Length + 1);//массив выходной строки динамически увеличиваем на единицу output_string[output_string.Length - 1] = temp;//добавляем число в текущий элемент выходной строки } if (input_string[i] == '+' || input_string[i] == '-') { m://т.к + и - имеют самый низкий приоритет, то при записывании этих операндов в стек //все остальные операции из стека должны переместится в выходную строку(исключение скобка) if (stack.Length != 0) //если стек еще не пуст { if (stack[stack.Length - 1] == "(")//если последний элемент стека открывающаяся скобка { Array.Resize(ref stack, stack.Length + 1); stack[stack.Length - 1] = input_string[i].ToString();//то в стек добавляется операция сложения или отрицания } else //иначе { Array.Resize(ref output_string, output_string.Length + 1); output_string[output_string.Length - 1] = stack[stack.Length - 1];//в выходную строку добавляется последняя операция из стека Array.Resize(ref stack, stack.Length - 1);//у стека удаляется последний элемент goto m;//возврат на проверку находится ли на вершине стека еще какая либо операция } stack[stack.Length - 1] = input_string[i].ToString();//на вершину стека помещается операция + или - } else { Array.Resize(ref stack, stack.Length + 1); stack[stack.Length - 1] = input_string[i].ToString();//если стек не пуст то в стек добавляется операция сложения или отрицания } } if (input_string[i] == '*' || input_string[i] == '/') { if (stack.Length != 0)//если стек еще не пуст { if (stack[stack.Length - 1] != "*" && stack[stack.Length - 1] != "/")//если на вершине стека не располагается * или / { Array.Resize(ref stack, stack.Length + 1); stack[stack.Length - 1] = input_string[i].ToString(); } else //если на вершине стека располагается * или / {//то т.к приоритеты операций одинаковые... Array.Resize(ref output_string, output_string.Length + 1); output_string[output_string.Length - 1] = stack[stack.Length - 1];//...элемент с вершины стека передается в выходную строку(массив) stack[stack.Length - 1] = input_string[i].ToString();//на вершину стека становится текщая операция умножения или деления } } else { Array.Resize(ref stack, stack.Length + 1); stack[stack.Length - 1] = input_string[i].ToString();//если стек не пуст то в стек добавляется операция умножения или деления } } if (input_string[i] == '(') {//найдена открывающаяся скобка которая автоматически добавляется в стек Array.Resize(ref stack, stack.Length + 1); stack[stack.Length - 1] = input_string[i].ToString(); } if (input_string[i] == ')') {//найдена закрывающаяся скобка int k_t = stack.Length - 1; while (stack[k_t] != "(")//некий цикл который начиная с конца стека перемещается влево в поисках открывающиейся скобки k_t--;//после цикла здесь хранится индекс открывающейся скобки int j; for (j = k_t+1; j < stack.Length; j++)//все операции которые хранились в стеке после "(" переносятся в выходную строку { Array.Resize(ref output_string, output_string.Length + 1); output_string[output_string.Length - 1] = stack[j]; } Array.Resize(ref stack,stack.Length-j);//стек уменьшается на количество переданных операций } if (input_string[i] == '^')//т.к у возведения в степень самый большой приоритет, его автоматически добавляют в выходную строку { Array.Resize(ref stack, stack.Length + 1); stack[stack.Length - 1] = input_string[i].ToString(); } } //всю ВХодную строку проверили теперь в стеке и в ВЫХодной строке содержатся некоторые данные //объединяем выходную строку со стеком Array.Resize(ref output_string, output_string.Length + stack.Length); Array.Reverse(stack);//это просто что бы не парится и не создавать цкл который будет идти задом на перед //т.к иначе есть свои нюансы в которые я вдаваться не хочу for (int i = output_string.Length - stack.Length; i < output_string.Length;i++) output_string[i] = stack[k++]; string t="";//сформировали из выходной строки(массива) строку for (int i = 0; i < output_string.Length; i++) if (i != output_string.Length-1) t += output_string[i] + " "; else t += output_string[i]; return t;//передали полученную строку } public double Solution(string OPZ_String) { string[] mas = OPZ_String.Split(' ');//нарезаем строку в виде Обратной польской записи в массив элементов string temp_string; for(int i=0;i<mas.Length;i++) switch (mas[i]) { case "+"://если найдена операция сложения temp_string = (double.Parse(mas[i - 2]) + double.Parse(mas[i - 1])).ToString();//выполняем сложение и переводим ее в строку richTextBox1.AppendText(mas[i - 2] +"+"+ mas[i - 1]+"="+temp_string+"\n"); mas[i - 2] = temp_string;//на место 1-ого операнда записывается результат (как если бы a=a+b) for (int j = i - 1; j < mas.Length - 2; j++)//удаляем из массива второй операнд и знак арифм действия mas[j] = mas[j + 2]; Array.Resize(ref mas,mas.Length-2);//обрезаем массив элементов на 2 удаленнх элемента i -= 2; break; case "-"://далее все аналогично temp_string = (double.Parse(mas[i - 2]) - double.Parse(mas[i - 1])).ToString(); richTextBox1.AppendText(mas[i - 2] + "-" + mas[i - 1] + "=" + temp_string + "\n"); mas[i - 2] = temp_string; for (int j = i - 1; j < mas.Length - 2; j++) mas[j] = mas[j + 2]; Array.Resize(ref mas, mas.Length - 2); i -= 2; break; case "*": temp_string = (double.Parse(mas[i - 2]) * double.Parse(mas[i - 1])).ToString(); richTextBox1.AppendText(mas[i - 2] + "*" + mas[i - 1] + "=" + temp_string + "\n"); mas[i - 2]=temp_string; for (int j = i - 1; j < mas.Length - 2; j++) mas[j] = mas[j + 2]; Array.Resize(ref mas, mas.Length - 2); i -= 2; break; case "/": temp_string = (double.Parse(mas[i - 2]) / double.Parse(mas[i - 1])).ToString(); richTextBox1.AppendText(mas[i - 2] + "/" + mas[i - 1] + "=" + temp_string + "\n"); mas[i - 2] = temp_string; for (int j = i - 1; j < mas.Length - 2; j++) mas[j] = mas[j + 2]; Array.Resize(ref mas, mas.Length - 2); i -= 2; break; case "^": temp_string = (Math.Pow(double.Parse(mas[i - 2]),double.Parse(mas[i - 1]))).ToString(); richTextBox1.AppendText(mas[i - 2] + "^" + mas[i - 1] + "=" + temp_string + "\n"); mas[i - 2] = temp_string; for (int j = i - 1; j < mas.Length - 2; j++) mas[j] = mas[j + 2]; Array.Resize(ref mas, mas.Length - 2); i -= 2; break; } return double.Parse(mas[0]); } private void button3_Click(object sender, EventArgs e) { double result = Solution(Create_OPZ(textBox1.Text)); this.Text ="Ответ: "+ result.ToString(); }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д