Python中的反向波兰计算器

时间:2015-09-12 23:54:06

标签: python

我正在尝试用Python构建一个反向抛光计算器,这就是我所知道的。它似乎工作,直到我尝试运行PRT,此时我从文本文件中获取最后一个数字,而不是从上一次计算附加到堆栈的结果。 Python不是我的常用语言,所以我为你将要看到的内容道歉。

    def is_number(ln):
        try:
            int(ln)
            return True
        except ValueError:
            return False

    def main():
        stack = []
        # Open file
        infile = open('math.txt', 'r')

        line = infile.readline()

        while line != '':
            if is_number(line):
                line = int(line)
                stack.append(line)
            if line in ['ADD', 'SUB', 'MUL', 'DIV']:
                if line=='ADD': result = stack.pop() + stack.pop()
                if line=='SUB': result = stack.pop() - stack.pop()
                if line=='MUL': result = stack.pop() * stack.pop()
                if line=='DIV': result = stack.pop() / stack.pop()
                print(result)
                stack.append(result)
            if line=='PRT': print(stack.pop())
            if line=='STOP': exit()
            line = infile.readline()

        # Close file
        infile.close()

    # Call main function

    main()

math.txt:

    1
    2
    3
    4
    5
    6
    ADD
    PRT

我猜测问题可能与换行符或readline有关,但我只是不用Python编写,所以我不确定。

2 个答案:

答案 0 :(得分:1)

readline()返回包含尾随lf或crlf的行,所以我不确定这部分是如何工作的,除非你刚刚将raw_input更改为文件读取。在任何情况下,程序与该数据集上的工作代码之间的最短距离是剥离线。你可以用你当前的数据做一个rstrip,但我只是剥离双方。像这样修改你的程序:

     while line != '':
+        line = line.strip()
         if is_number(line):
             line = int(line)

但这仍然不是很强大。这是一个修改版本,首先处理行,然后运行相同的算法。但我鼓励你在评论中研究和理解由spectras提供的要点,因为它显示了比这更有用的Python习语:

def is_number(ln):
    try:
        int(ln)
        return True
    except ValueError:
        return False

def main():
    with open('math.txt', 'r') as f:
        lines = (line.strip() for line in f)
        lines = [line for line in lines if line]

    stack = []
    for line in lines:
        if is_number(line):
            stack.append(int(line))
        elif line in ['ADD', 'SUB', 'MUL', 'DIV']:
            if line=='ADD': result = stack.pop() + stack.pop()
            if line=='SUB': result = stack.pop() - stack.pop()
            if line=='MUL': result = stack.pop() * stack.pop()
            if line=='DIV': result = stack.pop() / stack.pop()
            print(result)
            stack.append(result)
        elif line=='PRT':
            print(stack.pop())
        elif line=='STOP':
            exit()
        else:
            raise ValueError("Unknown line: %s" % line)

# Call main function

main()

答案 1 :(得分:0)

Here是我对后缀表达式求值程序的实现。

此代码期望表达式以空格分隔的字符串形式。你可以用;

with open('math.txt') as f:
    expr = f.read()

此代码中最有用的技巧是使用字典将运算符名称映射到函数。例如,具有两个参数的运算符;

from operator import add, sub, mul, truediv, pow

_binops = {'+': add, '-': sub, '*': mul, '/': truediv, '**': pow}

这会将所有if语句替换为;

b, a = stk.pop(), stk.pop()
stk.append(_binops[i](a, b))

使用_binops[i]从字典中选择一个函数对象。 调用此函数对象时,将从堆栈中弹出值。

IPython中的交互式示例;

In [1]: %cpaste
Pasting code; enter '--' alone on the line to stop or use Ctrl-D.
:from operator import add, sub, mul, truediv, pow
:_binops = {'+': add, '-': sub, '*': mul, '/': truediv, '**': pow}
:--

In [2]: _binops['+']
Out[2]: <function _operator.add>

In [3]: _binops['+'](1, 2)
Out[3]: 3

github上显示的完整代码也实现了一些只接受一个参数的运算符,如三角函数,并提供了一些常量。

只需更改ADD词典,就可以轻松修改为接受+而不是_binops;

_binops = {'+': add, 'add': add, '-': sub, 'sub': sub,
           '*': mul, 'mul': mul, '/': truediv, 'div': truediv,
           '**': pow, 'pow': pow}