用括号将代数表达式转换为RPN(反向波兰表示法)形式

时间:2014-10-04 10:04:11

标签: python python-2.7

from sys import stdin
t=int(stdin.readline())
while(t):
    s=stdin.readline()
    str = []
    top=-1
    for i in range(0, len(s)):
        c=s.index(i)
        if(c>='a' and c<='z'):
            print(c)
        elif(c=='('):
            pass
        elif(c==')'):
            print(str[top])
            top-=1
        else:
            top+=1
            str[top] = c
    t-=1

输入:

1
(a+b)

错误:

Traceback (most recent call last):
  File "C:\Users\Anurag\AppData\Roaming\NetBeans\8.0.1\nb_test_runner.py", line 216, in <module>
    module = __import__(module_name, globals(), locals(), module_name)
  File "__pyclasspath__/opn.py", line 8, in <module>
Finished in 0.0 seconds.
TypeError: expected a str
0 tests, 0 failures, 0 errors

提供1(a+b)作为输入后,会显示错误。

1 个答案:

答案 0 :(得分:1)

报告的错误正在发生,因为s.index()没有按照您的想法执行。 s.index(substr)返回s中的substr索引。有关详细信息,请参阅文档。试试

c = s[i]

甚至更好,将for循环的开头更改为

for c in s:

您的代码还有其他一些问题。例如,如果str[top]是空列表,str将失败。

以下代码将会运行,但zstr = [None]*20行是一个创可贴解决方案&amp;你真的需要在这里使用更好的逻辑。此外,您当前的算法要求表达式为括号,这有点限制。

from sys import stdin

t = int(stdin.readline())
while t:
    s = stdin.readline()
    zstr = [None]*20
    top = -1
    for c in s:
        if c.islower():
            print(c)
        elif c=='(':
            pass
        elif c==')':
            print(zstr[top])
            top -= 1
        else:
            top += 1
            zstr[top] = c
    t-=1

<强>测试

echo -e "2\n(x-y)\n((a+b)*(c+d))" | python qtest.py

<强>输出

x
y
-
a
b
+
c
d
+
*

修改

在一行中获取所有输出的有效方法是将输出字符串收集到一个列表中,然后将它们连接成一个字符串。 OTOH,将它们保存在列表中可能很有用。

另外,在可行的情况下,最好将处理逻辑与输入和输出分开。当然,对于计算器程序,这可能不实用。

<强> rpntest.py

#! /usr/bin/env python

''' Transform an algebraic expression with brackets into RPN (Reverse Polish Notation) form
From http://stackoverflow.com/questions/26191707/transform-an-algebraic-expression-with-brackets-into-rpn-reverse-polish-notatio
'''

import sys
import readline

def to_rpn(s):
    rpn = []
    zstr = [None] * 20
    top = -1
    for c in s:
        if c.islower():
            rpn.append(c)
            #print c
        elif c=='(':
            pass
        elif c==')':
            rpn.append(zstr[top])
            #print zstr[top]
            top -= 1
        else:
            top += 1
            zstr[top] = c
    return ' '.join(rpn)


def main():
    #for line in sys.stdin:
    while True:
        try:
            line = raw_input()
        except EOFError:
            break
        if line == '':
            continue
        rpn = to_rpn(line)
        print rpn


if __name__ == '__main__':
    main()

我已经改变了程序的输入逻辑了一点。现在您不需要指定要转换的表达式数。该程序仍然每行读取一个代数表达式,但它忽略空行。通过导入readline,它还为您提供了一些行编辑功能,因此可以使用箭头键。要退出程序,你需要发送一个文件结束信号 - 在Linux上的Ctrl-D,我认为在Windows上它是Ctrl-Z。您仍然可以将输入输入到程序中,例如echo -e "(x-y)\n((a+b)*(c+d))" | python rpntest.py