выпуск калькулятора - PullRequest
1 голос
/ 09 октября 2009

хочу разработать специальный калькулятор .. и я пришел к такой проблеме: Х = 1 + (12 * 4 + 2) мне нужно сначала получить количество операндов как здесь у меня есть два операнда 1 и (12 * 4 + 2) как я могу отличить внешний + от внутреннего?

спасибо

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

Я реализую алгоритм объединения в Java (точно так же, как делает интерпретатор Prolog, когда вы даете ему два выражения)

вот алгоритм:

function unify(E1, E2);
    begin
        case
            both E1 and E2 are constants or the empty list:
                if E1 = E2 then return {}
                else return FAIL;
            E1 is a variable:
                if E1 occurs in E2 then return FAIL
                 else return {E2/E1}
            E2 is a variable
                if E2 occurs in E1 then FAIL
                    else return {E1/E2}
            either E1 or E2 are empty then return FAIL
            otherwise:
                begin
                    HE1 := first element of E1;
                    HE2 := first element of E2;
                    SUBS1 := unify(HE1, HE2);
                    if SUBS1 := FAIL then return FAIL;
                    TE1 := apply(SUBS1, rest of E1);
                    TE2 := apply(SUBS1, rest of E2);
                    SUBS2 := unify(TE1, TE2);
                    if SUBS2 = FAIL then return FAIL;
                         else return composition(SUBS1, SUBS2)
                end
            end

Теперь мой вопрос: есть ли у меня такой вклад: а (X, Y) = A (B (C, Y), Z), ..

как я могу извлечь количество (и значения) элементов (т. Е. X и Y для первого выражения)

Я пришел к различным новым методам для меня, когда я прочитал и попытался решить эту проблему .. как Lexical Analysis, Parsing, я понятия не имею о Lexical Alanysis, хотя я знаю синтаксический анализ и токены (в строковой манере), более того, я думаю, что это не решит мою проблему .. Сейчас я пытаюсь реализовать то, что сказал Джои Адамс. Думаю, это полезно для моей проблемы.

Сори за этот очерк, парень ... спасибо за помощь

Ответы [ 7 ]

5 голосов
/ 09 октября 2009

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

При этом я бы посоветовал вам начать с Google, чтобы узнать некоторые термины и узнать:

Токенизация и Разбор (извлечение отдельных компонентов из строки.)

Оценка инфикса (взятие пары операндов и промежуточного оператора и сохранение ответа)

Оценка постфикса (принимая пару операндов и следующий оператор - это пока не имеет смысла, но, вероятно, будет после того, как вы немного прочтете)

.. и для дальнейшего чтения:

Дизайн компилятора

... и, если у вас возникнут конкретные вопросы, продолжайте посещать этот сайт. Не забудьте поискать ответы на вопросы, подобные вашим, которые уже задавались!

3 голосов
/ 09 октября 2009

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

X

  =
 /
X

  =
 / \
X   1

  =
 / \
X   +
   /
  1

  =
 / \
X   +
   / \
  1   (

  =
 / \
X   +
   / \
  1   (
       |
       12

  =
 / \
X   +
   / \
  1   (
       |
       *
      /
     12

  =
 / \
X   +
   / \
  1   (
       |
       *
      / \
     12  4

  =
 / \
X   +
   / \
  1   (
       |
       +
      /
     *
    / \
   12  4

  =
 / \
X   +
   / \
  1   (
       |
       +
      / \
     *   2
    / \
   12  4

  =
 / \
X   +
   / \
  1   ( )
       |
       +
      / \
     *   2
    / \
   12  4

Алгоритм проталкивания таков: поместите новый токен справа от последнего вставленного токена как дочерний, затем заставьте его всплыть до тех пор, пока он не будет удовлетворять порядку операций (более низкий приоритет превосходит более высокий приоритет, и ничто не идет выше открывающая скобка (то есть '('), пока она не будет закрыта (т.е. '(...)').

Вот моя реализация парсера такого типа в eC: http://www.funsitelots.com/pub/ecas0.zip. Вам понадобится Ecere SDK для его сборки. Посмотрите в form1.ec метод PushOperator. Извините, если это не самый простой код в мире для чтения.

1 голос
/ 09 октября 2009

Я бы взглянул на Шаблон проектирования интерпретатора . Гугл это "шаблон" с калькулятором и есть несколько приличных хитов, например этот .

0 голосов
/ 18 июня 2012

Вот фантастическая ссылка, которую я нашел, изучив ответ Боба Кауфмана:

users.cis.fiu.edu / ~ Вайс / dsj2 / код / ​​Evaluator.java

Это всего лишь код. Вот подробное объяснение (хотя он использует C ++, но логика точно такая же): http://www.lawrence.edu/fast/greggj/CMSC270/Infix.html

0 голосов
/ 09 октября 2009

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

1 - remove all decimals and periods from the input
2 - Use a regular expression to find / remove any parenthesis and the stuff in between them
3 - Use the remaining operations to guess at the number of operands

For example
Your input : 
1+(12*4+2)
1 - remove all #'s and .'s
  +(*+)
2 - remove all ()'s and internals
  +
3 - guess number of operands
  1 operation, so 2 operands

как я уже сказал, это довольно плохо и легко потерпит неудачу. Тем не менее, этого может быть достаточно, чтобы вы начали. После небольшого использования вы начнете замечать проблемы и, надеюсь, начнете понимать, почему вам нужно более надежное решение.

НТН

0 голосов
/ 09 октября 2009

Вы также можете взглянуть на некоторые движки формул, такие как JFormula (есть и другие), написанные на Java. У них будет собственный синтаксис, необходимый для формул, и некоторые операции синтаксического анализа все еще могут быть задействованы, но вы сможете обрабатывать математические выражения и порядок вычислений через механизм.

0 голосов
/ 09 октября 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...