Advertisement
Sanlover

Untitled

Oct 5th, 2020
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.03 KB | None | 0 0
  1. package com.company;
  2.  
  3. import java.util.Scanner;
  4.  
  5. public class Main {
  6.  
  7.     public static void main(String[] args) {
  8.         Scanner in = new Scanner(System.in);
  9.         do {
  10.             System.out.print("Введите выражение: "); //запрашиваем выражение
  11.             String str = in.nextLine(); //считываем выражение
  12.             if (check_str(str)) { //проверяем выражение на коректность
  13.                 System.out.println("Результат: " + calculate(str)); //считаем и выводим ответ
  14.             }
  15.             System.out.print("Введите e для выхода из программы, либой другой символ для повторения: ");
  16.         } while (in.nextLine().compareTo("e") != 0); //Если необходимо, начинаем новый цикл
  17.     }
  18.  
  19.     public static double calculate(String str) {
  20.         int pos = find_first_mot(str); //получаем позицию самой НЕ приоритетной операции
  21.         if (pos == -1) // строка состоит из выражения в скобка или это число
  22.             if (str.charAt(0) == '(' && str.charAt(str.length() - 1) == ')') //если выражение состоит из скобок
  23.                 return calculate(str.substring(1, str.length() - 1)); //считаем внутри скобок
  24.             else
  25.                 return Double.parseDouble(str); // если внутри число
  26.         else // если найдена операция, то выполняем ее
  27.             switch (str.charAt(pos)) {
  28.                 case '+':
  29.                     return calculate(str.substring(0, pos)) + calculate(str.substring(pos + 1));
  30.                 case '-':
  31.                     return calculate(str.substring(0, pos)) - calculate(str.substring(pos + 1));
  32.                 case '*':
  33.                     return calculate(str.substring(0, pos)) * calculate(str.substring(pos + 1));
  34.                 case '/':
  35.                     return calculate(str.substring(0, pos)) / calculate(str.substring(pos + 1));
  36.             }
  37.         return -1;
  38.     }
  39.  
  40.     public static int find_first_mot(String str) {
  41.         int cnt = 0; // счетчик скобок
  42.         int pos = -1, priority = 100; //pos - позиция элемента, priority - наименьший приоритет
  43.         for (int i = str.length() - 1; i > 0; i--) // проходимся по всему выржению
  44.             if (str.charAt(i) == '(')
  45.                 cnt++;
  46.             else if (str.charAt(i) == ')')
  47.                 cnt--;
  48.             else if (cnt == 0) // если мы сейчас не в скобка, то обрабатываем символ
  49.                 if (priori(str.charAt(i)) < priority)//если оператор имеее меньший приоритет, то обрабатываем его
  50.                     if (str.charAt(i) == '+' || str.charAt(i) == '-') //если это минус или плюс, то они имеют наименьший прир. и дальше искать нет необходимости
  51.                         return i;
  52.                     else {
  53.                         pos = i;
  54.                         priority = priori(str.charAt(i));
  55.                     }
  56.         return priority == 100 ? -1 : pos; //если нет оперторов или все выражение находится в скобка возвращаем -1, иначе pos
  57.     }
  58.  
  59.     /*
  60.     проверяет строку на коректность
  61.      */
  62.     public static boolean check_str(String str) {
  63.         int n = str.length();
  64.         int cnt = 0;
  65.         for (int i = 0; i < n; i++) {
  66.             if (str.charAt(i) == '(') { // если перед скобкой стоит не скобка или не другая скобка - это некоректно.
  67.                 cnt++;
  68.                 if (i - 1 >= 0 &&
  69.                         !(str.charAt(i - 1) == '*' || str.charAt(i - 1) == '/' ||
  70.                                 str.charAt(i - 1) == '+' || str.charAt(i - 1) == '-' ||
  71.                         str.charAt(i - 1) == '(')){
  72.                     System.out.println("Нет действий перед скобкой");
  73.                     return false;
  74.                 }
  75.             } else if (str.charAt(i) == ')') {// если после скобки стоит не скобка или не другая скобка - это некоректно.
  76.                 cnt--;
  77.                 if (i + 1 < str.length() &&
  78.                         !(str.charAt(i + 1) == '*' || str.charAt(i + 1) == '/' ||
  79.                                 str.charAt(i + 1) == '+' || str.charAt(i + 1) == '-' ||
  80.                                 str.charAt(i + 1) == ')')) {
  81.                     System.out.println("Нет действий после скобки");
  82.                     return false;
  83.                 } //если найден неизвестный символ
  84.             } else if (!(str.charAt(i) >= '0' && str.charAt(i) <= '9' ||
  85.                     str.charAt(i) == '*' || str.charAt(i) == '/' ||
  86.                     str.charAt(i) == '+' || str.charAt(i) == '-')) {
  87.                 System.out.println("Неизвестный символ: " + str.charAt(i));
  88.                 return false;
  89.             }
  90.         }
  91.  
  92.         if (cnt != 0) { //в выражении неправильное кол-во скобок
  93.             System.out.println("Не правильное кол-во скобок.");
  94.             return false;
  95.         }
  96.         return true;
  97.     }
  98.  
  99.     /*
  100.     возвращает приоритет операции
  101.      */
  102.     public static int priori(char mot) {
  103.         switch (mot) {
  104.             case '+':
  105.             case '-':
  106.                 return 1;
  107.             case '*':
  108.             case '/':
  109.                 return 2;
  110.             default:
  111.                 return 101; // для всего остального
  112.         }
  113.     }
  114. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement