2013-11-08 3 views
0

Хорошо, поэтому я пытаюсь сделать решатель выражения как строку, так что пользователь может ввести строку, например 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; 
} 
} 
+0

Разберите его в дерево выражений. – Kevin

+0

http://stackoverflow.com/questions/1432245/java-parse-a-mathematics-expression-given-as-a-string-and-return-a-number – JNL

+0

Остерегайтесь страшных целых делений. –

ответ

1

Используйте две for петли.

В вашем первом цикле найдите * и / операторов. Оцените эту часть и замените эту часть строки результатом оценки.

В вашей второй петле сделайте все + и -, как вы уже делаете.

Для примера, который вы используете, 2+4*5/10, ваш первый цикл будет искать * или /. Найдя *, он оценивает 4*5. Это 20, поэтому строка изменена на 2+20/10. Еще раз проверьте, и он находит / и изменяет строку на 2+2.

Теперь вы проходите вторую петлю и получаете 4.

+0

Вот что я думал, что должен был сделать, но я не уверен, как заменить 4 * 5 на 20. – user2967415

+0

Начните с поиска индекса подстроки '4 * 5', выполните умножение на эту подстроку, поверните результат в строку, затем используйте метод «replace». – nhgrif

+0

Хорошо, я полагаю, что моя настоящая проблема в том, что я не знаю, как сделать '4 * 5' подстрокой. Я знаю, что в этом случае это должно быть как 'E.substring (E.indexOf ('4'), E.indexOf ('5') + 1)', но я не знаю, как указать, какой символ должен быть начальный индекс и который должен быть конечным индексом, когда 'E' может быть любой строкой. Спасибо за помощь до сих пор! – user2967415

1

Вам нужно сделать два шага вместо одного. На первом этапе вы анализируете уравнение в reverse polish notation, затем на втором этапе вы выполняете это и вычисляете результаты. Хороший бонус - вы получаете поддержку скобок (почти) бесплатно :-)

+0

На самом деле ответ @nhgnf намного проще, если вам не нужно выходить за рамки четырех основных операций. – PiotrK

+0

Ха-ха, да ... но мне нравится ваш ответ лучше на самом деле. – nhgrif

1

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

Вам необходимо сделать следующие шаги в этом порядке, иначе вы нарушите порядок операций.

  1. Ищите самый правый знак + знак. Если есть такой +, используйте рекурсию для оценки подвыражения слева от него, затем подвыражения справа от него, затем добавьте их и верните результат.
  2. Если знак + отсутствует, тогда найдите самый правый знак, которому предшествует число (то есть вычитание, а не отрицание). Если есть такое -, используйте рекурсию для оценки подвыражения слева от него, затем подвыражения справа от него, затем вычтите их и верните результат.
  3. Если нет знака + или -, найдите самый правый знак *. Если есть такой *, используйте рекурсию для оценки подвыражения слева от него, затем подвыражения справа от него, затем умножьте их и верните результат.
  4. Если нет знака +, - или *, тогда найдите самый правый знак *. Если есть такой *, то используйте рекурсию для оценки подвыражения слева от него, затем подвыражения справа от него, затем разделите их и верните результат. Если вы используете целые числа, вам нужно подумать о том, хотите ли вы целочисленное деление или с плавающей запятой. Вы также можете сделать некоторую проверку, делящую на ноль.
  5. Если нет +, -, * или /, тогда все, что у вас есть, это цифры и пробелы. Может быть, отрицательный знак. Разделите пробел, проанализируйте его и верните.

Пример: "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)», поэтому порядок операций будет выполнен правильно.

 Смежные вопросы

  • Нет связанных вопросов^_^