2013-11-07 4 views
0

CS Студент здесь. Я хочу иметь возможность взять строку, такую ​​как «2 + 2 * 3/2-2», и оценить ее (= 3). Но я не уверен, как структурировать код, чтобы следовать правильному порядку операций. Вот код для умножения и деления:Строковые выражения с четырьмя операторами

int r = 1; 
    int n = 0; 
    char op = '*'; 

    for (int i = 0; i < E.length(); i++) 
     if (E.charAt(i)=='*'||E.charAt(i)=='/') 
     { 
      if (op == '*') 
       r *= n; 
      else 
       r /= n; 
      n = 0; 
      op = E.charAt(i); 
     } 
     else 
      n = n*10 + (E.charAt(i)-'0'); 

    if (op == '*') 
     r *= n; 
    else 
     r /= n; 

    return r; 

Спасибо за чтение!

+0

были бы какие-либо скобки? –

+1

Вы можете найти интересную информацию по адресу http://stackoverflow.com/questions/3422673/evaluating-a-math-expression-given-in-string-form –

ответ

2

Используйте двоичное дерево, где каждый узел является арифметическим оператором, а листы - значениями.

+1

+1 Расчет производится затем снизу вверх от листьев до достижения корневой узел. –

+0

Я не уверен, что это такое. Я только начинаю программировать. Даже не делал этого больше, чем через пару месяцев. – CSpadawan

0

Это именно то, что должно сделать Interpreter pattern. Ваши математические операции - это в основном грамматика - все, что вам нужно сделать, это грамматика. Используйте шаблон Interpreter для анализа вашего математического утверждения, а затем используйте то, что он выплевывает, чтобы выполнить необходимые операции.

0

Используйте обратную польский обозначение, чтобы представить формулу в форме, удобной для вычислений. Вы можете прочитать о RPN здесь: версия http://en.wikipedia.org/wiki/Reverse_Polish_notation

RPN из ваших 2 + 2 * 3/2-2 будет 2 3 2 * 2/2 - +

Тогда алгоритм так: Предположим каждый знак из версии RPN является элементом из массива символов. Вы берете элемент из массива и, если это число, помещаете его в стек, если это оператор, берут два элемента из стека и выполняют операцию. Результат должен снова приземлиться на стек. Повторяйте, пока не достигнете последнего элемента массива. В конце будет только один элемент вашего стека, который будет вашим ответом.

Давайте визуализировать: итерация символ # содержание стека 1 # 2 -> 2 2 # 2 -> 2,2 3 # 3 -> 3,2,2 4 # * -> 6,2 5 # 2 -> 2,6,2 6 #/-> 3,2 7 # 2 -> 2,3,2 8 # - -> 1,2 9 # + -> 3

0

Вам нужно разобрать выражение. Простой метод рекурсивного спуска может сделать:

double expression(const char **p) { 
    double rv = term(p); 
    while (**p) { 
     if (**p = '+') { 
      ++*p; 
      rv += term(p) 
     } else if (**p = '-') { 
      ++*p; 
      rv -= term(p); 
     } else 
      break; } 
    return rv; } 

double term(const char **p) { 
    double rv = factor(p); 
    while (**p) { 
     if (**p = '*') { 
      ++*p; 
      rv *= factor(p) 
     } else if (**p = '/') { 
      ++*p; 
      rv /= factor(p); 
     } else 
      break; } 
    return rv; } 

double factor(const char **p) { 
    return strtod(p, (char **)&p); 
} 

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

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