#Leet Code# Evaluate Reverse Polish Notation

描述:计算逆波兰表达法的结果

Sample:

  ["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9
  ["4", "13", "5", "/", "+"] -> (4 + (13 / 5)) -> 6

使用stack实现:

 1 def is_op(c):
 2     return c in ['+', '-', '*', '/']
 3 
 4 def divide(x, y):
 5     if (x * y) < 0:
 6         return -1 * ((-x)/y)
 7     return x/y
 8 
 9 class Solution:
10     # @param tokens, a list of string
11     # @return an integer
12     def evalRPN(self, tokens):
13         opDict = {'+': lambda x,y: x+y,
14                   '-': lambda x,y: x-y,
15                   '*': lambda x,y: x*y,
16                   '/': divide}
17         record = []
18 
19         for item in tokens:
20             if is_op(item):
21                 second = record.pop()
22                 first = record.pop()
23                 record.append(opDict[item](first, second))
24             else:
25                 record.append(int(item))
26         return record[0]

使用树实现:

 1 def is_op(c):
 2     return c in ['+', '-', '*', '/']
 3 
 4 def divide(x, y):
 5     if (x * y) < 0:
 6         return -1 * ((-x)/y)
 7     return x/y
 8 
 9 class Tree:
10     def __init__(self, data):
11         self.data = data
12         self.parent = None
13         self.left = None
14         self.right = None
15 
16 class Solution:
17     # @param tokens, a list of string
18     # @return an integer
19     def __init__(self):
20         self.opDict = {'+': lambda x,y: x+y,
21                   '-': lambda x,y: x-y,
22                   '*': lambda x,y: x*y,
23                   '/': divide}
24 
25     def builtTree(self, tokens):
26         if not is_op(tokens[-1]):
27             return int(tokens[-1])
28 
29         # if element is an operator
30         cur_tree = Tree(tokens[-1])
31         top_tree = cur_tree
32 
33         for item in tokens[-2::-1]:
34             if cur_tree.right is None:
35                 if is_op(item):
36                     cur_tree.right = Tree(item)
37                     cur_tree.right.parent = cur_tree
38                     cur_tree = cur_tree.right
39                 else:
40                     cur_tree.right = int(item)
41 
42                 if cur_tree.right and cur_tree.left:
43                     cur_tree = self.getUpperNode(cur_tree)
44                 continue
45 
46             if cur_tree.left is None:
47                 if is_op(item):
48                     cur_tree.left = Tree(item)
49                     cur_tree.left.parent = cur_tree
50                     cur_tree = cur_tree.left
51                 else:
52                     cur_tree.left = int(item)
53 
54                 if cur_tree.right is not None and cur_tree.left is not None:
55                     cur_tree = self.getUpperNode(cur_tree)
56 
57         return top_tree
58 
59     # Move to upper node if cur node if full. If top_node return.
60     def getUpperNode(self, node):
61         while node.right is not None and node.left is not None:
62             if node.parent is None:
63                 return node
64 
65             node = node.parent
66 
67         return node
68 
69     def getValue(self, node):
70         if type(node) is type(1):
71             return node
72         else:
73             return self.getResult(node)
74 
75     def getResult(self, treeNode):
76         leftValue = self.getValue(treeNode.left)
77         rightValue = self.getValue(treeNode.right)
78 
79         result = self.opDict[treeNode.data](leftValue, rightValue)
80 
81         return result
82 
83     def evalRPN(self, tokens):
84         topNode = self.builtTree(tokens)
85 
86         if type(topNode) is type(1):
87             return topNode
88         else:
89             resultNum = self.getResult(topNode)
90             return resultNum

备注-1:if cur_node.right is None 不能用 if cur_node.right 因为cur_node.right 如果是数字0的话会有问题 当然 不转成int的话直接存string等到运算时再转int应该就可以这样写了

备注-2:python的除法跟c++不太一样 3/-5 = -1

结论:

根据问题的具体特性,选择合适的数据结构解决问题会差别很大

posted @ 2014-07-25 16:48  mess4u  阅读(121)  评论(0编辑  收藏  举报