Как добавить порядок операций в решатель выражений?
Хорошо, поэтому я пытаюсь сделать решатель выражения как строки, чтобы пользователь мог ввести строку, например, 2+4*5/10, и он напечатает ответ, 4. У меня есть написан некоторый код, но он не применяет порядок операций; он просто решает уравнение в порядке операторов - например, 2 + 4 * 5/10 даст 3, что неверно. Как сделать так, чтобы сначала выполнялись умножение и деление, а затем сложение и вычитание? Вот код, который я сейчас имею:
class Expressions
{
String E;
void SetE(String e)
{
E = e;
}
int EvalE()
{
int res = 0;
int temp = 0;
char op = '+';
for(int i=0;i<E.length();i++)
{
if(E.charAt(i)=='*'||E.charAt(i)=='/'||E.charAt(i)=='+'||E.charAt(i)=='-')
{
if(op=='*')res*=temp;
else if(op=='/')res/=temp;
else if(op=='+')res+=temp;
else res-=temp;
temp=0;
op=E.charAt(i);
}
else
{
temp = temp*10+E.charAt(i)-'0';
}
}
if(op=='*')res*=temp;
else if(op=='/')res/=temp;
else if(op=='+')res+=temp;
else res-=temp;
return res;
}
}
3 ответа
Разбейте выражение на два более простых выражения, затем используйте рекурсию.
Вы должны сделать следующие шаги именно в этом порядке, или вы испортите порядок операций.
- Ищите самый правый знак +. Если есть такой знак +, используйте рекурсию для вычисления подвыражения слева от него, затем подвыражения справа от него, затем добавьте их и верните результат.
- Если знака + нет, ищите крайний правый знак, которому предшествует число (то есть вычитание, а не отрицание). Если есть такое -, используйте рекурсию для вычисления подвыражения слева от него, затем подвыражения справа от него, затем вычтите их и верните результат.
- Если знака + или - нет, найдите самый правый знак *. Если есть такое *, используйте рекурсию для вычисления подвыражения слева от него, затем подвыражения справа от него, затем умножьте их и верните результат.
- Если знака +, - или * нет, найдите самый правый знак *. Если есть такое *, используйте рекурсию для вычисления подвыражения слева от него, затем подвыражения справа от него, затем разделите их и верните результат. Если вы используете целые числа, вам нужно подумать, хотите ли вы целочисленное деление или число с плавающей запятой. Вы могли бы также хотеть сделать некоторую проверку вокруг деления на ноль.
- Если нет +, -, * или /, то все, что у вас есть, это числа и пробелы. Возможно отрицательный знак. Удалите пробелы, разберите его и верните.
Пример: "6 - 5 - 4 + 3 * -2"
- Сначала разделите на + и используйте рекурсию, чтобы оценить "6 - 5 - 4 " и " 3 * -2".
- Для "6 - 5 - 4 ", разделите на второе - и используйте рекурсию для оценки "6 - 5 " и " 4 ".
- Для "6 - 5 " разделите на - и используйте рекурсию для оценки "6 " и " 5 ".
- Для " 3 * -2", разделите на *, потому что - не предшествует число. Используйте рекурсию для оценки " 3 " и " -2 ".
- Для каждого из "6 ", " 5 ", " 4 ", " 3 " и "-2" нет операторов, поэтому мы просто удаляем пустое пространство и анализируем.
- Результатом нашего расчета будет "((6-5)-4)+(3*-2)", поэтому порядок операций отработан правильно.
Вам нужно сделать два шага вместо одного. На первом шаге вы анализируете уравнение в обратной польской записи, затем на втором шаге вы проходите через это и вычисляете результаты. Приятный бонус - вы получаете поддержку скобок (почти) бесплатно:-)
Использовать два for
петли.
В первом цикле найдите *
а также /
операторы. Оцените эту часть и замените эту часть строки на результат оценки.
Во втором цикле сделайте все +
а также -
как ты уже делаешь.
Так что для примера, который вы используете, 2+4*5/10
, ваш первый цикл будет искать *
или же /
, Найдя *
оценивает 4*5
, Это 20
поэтому строка модифицируется в 2+20/10
, Проверьте еще раз, и он находит /
и изменяет строку в 2+2
,
Теперь вы проходите второй цикл и получаете 4
,