Страницы

Поиск по вопросам

вторник, 31 декабря 2019 г.

Как правильно обработать порядок арифметических операций?

#java #алгоритм


Делаю что-то вроде обработчика выражений, как в Excel...

Есть входящая строка String inputStr = "5+5-10/8+8*2" (любые числа и действия).

Как реализовать приоритет действий? Нужен алгоритм.
    


Ответы

Ответ 1



Эта задача решается с использованием стека через формирование и подсчёт Обратной Польской Нотации .

Ответ 2



вот решение Обратной Польской Нотации, должно работать проверьте. import java.util.LinkedList; public class Calc { static boolean isDelim(char c) { return c == ' '; } static boolean isOperator(char c) { return c == '+' || c == '-' || c == '*' || c == '/' || c == '%' || c == ','|| c == '^'; } static int priority(char op) { switch (op) { case '+': case '-': return 1; case '*': case '/': case '%': return 2; case ',': return 3; case '^': return 4; default: return -1; } } static void processOperator(LinkedList st, char op) { Double r = st.removeLast(); Double l = st.removeLast(); switch (op) { case '+': st.add(l + r); break; case '-': st.add(l - r); break; case '*': st.add(l * r); break; case '/': st.add(l / r); break; case '%': st.add(l % r); break; case ',': st.add(l - r); break; case '^': st.add(Math.pow(l, r)); break; } } public static Double eval(String s) { if (s.charAt(0) == '-'){ String buffer = s; s ="0 "; s+=buffer; System.out.println(s); } for (int i = 0; i < s.length(); i++){ if(s.charAt(i) == '(' && s.charAt(i+1) == '-'){ StringBuffer sb = new StringBuffer(s); sb.replace(i, i+2, "(0 - "); s = sb.toString(); System.out.println(s); } } LinkedList st = new LinkedList(); LinkedList op = new LinkedList(); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (isDelim(c)) continue; if (c == '(') op.add('('); else if (c == ')') { while (op.getLast() != '(') processOperator(st, op.removeLast()); op.removeLast(); } else if (isOperator(c)) { while (!op.isEmpty() && priority(op.getLast()) >= priority(c)) processOperator(st, op.removeLast()); op.add(c); } else { String operand = ""; while (i < s.length() && Character.isDigit(s.charAt(i)) || i < s.length() && s.charAt(i) == '.') operand += s.charAt(i++); --i; st.add(Double.parseDouble(operand)); } } while (!op.isEmpty()) processOperator(st, op.removeLast()); return st.get(0); } public static void main(String[] args) throws Exception { String exp = "12+3.6"; System.out.println(eval(exp)); String exp2 = "105 - 1"; System.out.println(eval(exp2)); String exp3 = "-105 - 1"; System.out.println(eval(exp3)); String exp4 = "(-105 - 1)"; System.out.println(eval(exp4)); String exp5 = "-2*(-2)"; System.out.println(eval(exp5)); } }

Ответ 3



порядок арифметических операций (приоритет) определяется скобками, например: 5+5*5=30 5+(5*5)=30 (5+5)*5=50

Комментариев нет:

Отправить комментарий