Хранение и оценка вложенных строковых элементов - PullRequest
2 голосов
/ 06 февраля 2012

Учитывая exampleString = "[9+[7*3+[1+2]]-5]" Как можно извлечь и сохранить элементы, заключенные в [] скобки, а затем оценить их по порядку?

1+2 --+
      |
  7*3+3 --+
          |
        9+24-5

Нужно ли создавать некий вложенный список?Извините за этот несколько широкий вопрос и плохой английский.

Я вижу, этот вопрос действительно слишком широкий ... Есть ли способ создать вложенный список из этой строки?Или, может быть, я должен просто выполнить поиск по каждому регулярному выражению и оценить каждый элемент?Параметр вложенного списка (если он существует) был бы более «чистым» подходом IMO, чем цикл по одной и той же строке и вычисление до тех пор, пока не будет [] скобок.

Ответы [ 3 ]

3 голосов
/ 06 февраля 2012

Посмотрите на модуль pyparsing и некоторые примеры, которые у них есть ( калькулятор с четырьмя функциями - это то, что вам нужно, и даже больше).

PS. В случае, если размер этого кода беспокоит вас, посмотрите еще раз: большая часть этого может быть удалена. Нижняя половина - просто тесты. Верхняя часть может быть отделена от таких вещей, как поддержка констант e / pi / ..., тригонометрических функций и т. Д. Я уверен, что вы можете сократить ее до 10 строк для того, что вам нужно.

2 голосов
/ 06 февраля 2012

Хорошей отправной точкой является алгоритм маневрового двора .

В сети доступно несколько реализаций Python;здесь one .

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

1 голос
/ 06 февраля 2012

Вот решение для регулярных выражений:

import re

def evaluatesimple(s):
  return eval(s)

def evaluate(s):
  while 1:
    simplesums=re.findall("\[([^\]\[]*)\]",s)
    if (len(simplesums) == 0):
      break
    replacements=[('[%s]' % item,str(evaluatesimple(item))) for item in simplesums]
    for r in replacements:
      s = s.replace(*r)
  return s

print evaluate("[9+[7*3+[1+2]]-5]")

Но если вы хотите использовать всю свинью и построить дерево для последующей оценки, вы можете использовать ту же технику, но сохранить выражения и подвыражения вdict:

def tokengen():
  for c in 'abcdefghijklmnopqrstuvwyxz':
    yield c

def makeexpressiontree(s):
  d=dict()
  tokens = tokengen()
  while 1:
    simplesums=re.findall("\[([^\]\[]*)\]",s)
    if (len(simplesums) == 0):
      break
    for item in simplesums:
      t = tokens.next()
      d[t] = item
      s = s.replace("[%s]"% item,t)
  return d

def evaltree(d):
  """A simple dumb way to show in principle how to evaluate the tree"""
  result=0
  ev={}
  for i,t in zip(range(len(d)),tokengen()):
    ev[t] = eval(d[t],ev)
    result = ev[t]
  return result

s="[9+[7*3+[1+2]]-5]"
print evaluate(s)
tree=makeexpressiontree(s)
print tree
print evaltree(tree)

(отредактировано для расширения моего ответа)

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