3

我对编程很陌生。这与python有关。所以想法是取3/5或最多3/5*2(最多两个运算符,注意运算符可以是+、-、/、*中的任何一个)之类的表达式并求解。空格可以存在于表达式中的任何位置。

用户输入表达式,比如 3/5,程序需要求解表达式并显示答案。我尝试过的如下。请注意,我只尝试了第一部分,一旦我可以正确拆分用户输入的原始表达式(这将是一个字符串),创建函数将是简单的部分:

expres= str(input("something:"))

ssplit= hit.partition("/")
onec= int((ssplit[0].lstrip()).rstrip())
twoc= (ssplit[1].lstrip()).rstrip()
threec= int((huns[2].lstrip()).rstrip())


print(onec,"...",twoc,"...",threec) #just a debug test print

因此,在上面,我可以将 3/5 之类的表达式拆分为三个单独的字符串:3、/ 和 5。我还可以删除运算符/操作数之前和之后的所有空格。我在拆分 4/5+6 之类的表达式时遇到问题,因为我无法为 ssplit[3] 或 ssplit[4] 输入代码,然后输入 3/5 之类的表达式,因为它不会被定义。基本上我需要你帮助找出如何拆分像 3/4-6 等的表达式。我还需要“”行的帮助,ssplit= hit.partition("/")以便它可以查看输入的表达式并同时使用 +、- 和 *。任何和所有的帮助表示赞赏。另外,如果我上面的代码看起来很讨厌而且效率低下,请给我批评。谢谢!

注意我不能,也不想使用 eval。操作顺序是必需的。我不能使用复杂的命令。我需要保持简单,我最多可以使用字符串库,在字符串/整数/浮点数等以及 if、and 等之间进行转换。陈述。我也可以使用函数。

4

3 回答 3

10

如果我不打算依赖外部库,我会这样做:

def parse(x):
    operators = set('+-*/')
    op_out = []    #This holds the operators that are found in the string (left to right)
    num_out = []   #this holds the non-operators that are found in the string (left to right)
    buff = []
    for c in x:  #examine 1 character at a time
        if c in operators:  
            #found an operator.  Everything we've accumulated in `buff` is 
            #a single "number". Join it together and put it in `num_out`.
            num_out.append(''.join(buff))
            buff = []
            op_out.append(c)
        else:
            #not an operator.  Just accumulate this character in buff.
            buff.append(c)
    num_out.append(''.join(buff))
    return num_out,op_out

print parse('3/2*15')

它不是最优雅的,但它可以让你获得合理的数据结构(就我而言)

现在代码实际解析和评估数字 - 这将在浮点中完成所有操作,但很容易更改......

import operator
def my_eval(nums,ops):

    nums = list(nums)
    ops = list(ops)
    operator_order = ('*/','+-')  #precedence from left to right.  operators at same index have same precendece.
                                  #map operators to functions.
    op_dict = {'*':operator.mul,
               '/':operator.div,
               '+':operator.add,
               '-':operator.sub}
    Value = None
    for op in operator_order:                   #Loop over precedence levels
        while any(o in ops for o in op):        #Operator with this precedence level exists
            idx,oo = next((i,o) for i,o in enumerate(ops) if o in op) #Next operator with this precedence         
            ops.pop(idx)                        #remove this operator from the operator list
            values = map(float,nums[idx:idx+2]) #here I just assume float for everything
            value = op_dict[oo](*values)
            nums[idx:idx+2] = [value]           #clear out those indices

    return nums[0]

print my_eval(*parse('3/2*15'))
于 2012-10-24T19:15:04.820 回答
2

这不是解析表达式的真正方法,您应该更多地研究词法分析器和解析器,例如PLYpyparsing。但是,如果您只想评估可以使用的表达式eval(expr)。请注意, eval 将执行您提供的任何代码,因此它并不安全。

编辑 这里有一个使用 pyparsing 的示例,应该可以帮助您入门:

解析示例

于 2012-10-24T19:04:44.923 回答
2

使用shlexStringIOPython 模块。在 Python 2.3+ 中:

>>> from StringIO import StringIO
>>> import shlex
>>> input = StringIO('3/4+5')
>>> list(shlex.shlex(input))
['3', '/', '4', '+', '5']
于 2012-10-24T20:21:01.263 回答