Калькулятор Java, как обрабатывать отрицательные числа

Я создаю калькулятор на Java и изо всех сил пытаюсь придумать способ обработки отрицательных чисел, пока я могу разобрать выражение, например это:

((4-3)*(4/2))*2

становится:

[4.0, -3.0, +, 4.0, 2.0, /, *, 2.0, *]

Однако я не знаю, как бы я поступил с выражениями, содержащими отрицания, например:

2*(-2-3)

Пока что у меня это есть, поэтому, когда встречается отрицательное значение, оно умножает число перед ним на -1 и добавляет + в конец списка, поэтому выражение становится таким:

[2.0, -2.0, -3.0, +, +, *]

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

Большое спасибо за любую помощь


person user3120023    schedule 06.01.2014    source источник
comment
Возможно, вы могли бы справиться с этим, добавив 0 перед любым отрицанием. Таким образом, 2*(-2-3) станет 2*(0-2-3).   -  person sp00m    schedule 06.01.2014
comment
Спасибо за быстрый ответ, я пробовал это, но когда у меня есть выражение типа 8*-2, я получаю список [8.0, 0.0, *, -2.0, +], который вызывает ответ -2   -  person user3120023    schedule 06.01.2014
comment
то вы разбираете его неправильно, 8*-2 должно быть [8, 0, 2, -, *], вы читаете 8 => [8], вы читаете *, затем вы вызываете разбор следующего аргумента, вы читаете - и 2 => [8, 0, 2, -], теперь вы завершаете * => [8, 0, 2, -, *]   -  person Vladp    schedule 06.01.2014
comment
может быть, вы должны опубликовать, как вы разбираете, проблема может быть там.   -  person Vladp    schedule 06.01.2014


Ответы (3)


Vladp правильно, но нужно добавить некоторые пояснения.

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

Проблема заключается в том, что вы не различаете бинарное вычитание и унарный инвертирует - символ/символ/оператор.

Таким образом, для

2*(-2-3)

Вы бы преобразовали это в AST как

       *
      / \
  - (b)  2
    / \
- (u)  3
  /
 2

где - (b) - двоичное вычитание, а - (u) - унарное отрицание.

или РПН как

2-3-2*  

И оценивая как

2 - 3 - 2 *
(-2) 3 - 2 *
(-5) 2 *
-10 

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

Таким образом, -5 с отрицанием равно -5
, а 5 с отрицанием равно -5.

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

person Guy Coder    schedule 06.01.2014

Сделайте два разных типа -,

тот, который работает с одним значением, просто сделав его отрицательным:

-(2+3)
[2, 3, +, type1-]

и второй, который работает как +:

2-3
[2, 3, type2-]

вместе у вас должно получиться:

2--3
[2, 3, type1-, type2-]

-2-(-3)
[2, type1-, 3, type1-, type2-]

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

person Vladp    schedule 06.01.2014

Что ж, вот мои два цента:

Я подозреваю, что разбиение уравнения, содержащего скобки, внутри скобок и т. д., на массив, как вы сделали, приведет к множеству трудностей. Вместо этого я предлагаю вам программно углубиться в самые глубокие родительские элементы, обработать данные и работать вовне. В Google могут быть онлайн-примеры того, как это сделать.

person user2810910    schedule 06.01.2014