python演算法 字串表示式的計算

2021-07-14 17:12:40 字數 3734 閱讀 5610

preface:最近有個面試,被要求給出乙個字串表示式,計算出結果。本以為是見到過的,想著用乙個棧,然後被面試官打斷說你這樣是有問題的,然後想了說用樹,又被打斷說是有問題的,再仔細想想。結果還是沒整出來。哎。回來翻了下leetcode發現有兩道類似。

leetcode 224 basic calculator 有點類似,可這特麼只用加減和括號不用乘除啊,媽的智障。這題用棧ac了。

leetcode 227 basic calculator ii 也有點類似,只是差了括號。

但這兩道還是不夠。翻書加上與同仁的討論,發現只需要將表示式化為二叉樹的字尾表示式即可,有了字尾表示式,就比較簡單了。字尾表示式是能夠唯一確定表示式樹的。後序遍歷表示式樹即可。用棧對字尾表示式進行處理也可以的。主要還是需要將字串表示式化為字尾表示式。

另外,計算字串表示式,python有個內建函式eval(),直接使用eval("1+2*(3-1)-4")即可。

coding:

# -*- coding: utf-8 -*-

"""created on sun jul 10 15:39:28 2016

@author: administrator

"""operator_precedence =

def postfix_convert(exp):

'''將表示式字串,轉為字尾表示式

如exp = "1+2*(3-1)-4"

轉換為:postfix = ['1', '2', '3', '1', '-', '*', '+', '4', '-']

'''stack = #運算子棧,存放運算子

postfix = #字尾表示式棧

for char in exp:

# print char, stack, postfix

if char not in operator_precedence:#非符號,直接進棧

else:

if len(stack) == 0:#若是運算子棧啥也沒有,直接將運算子進棧

else:

if char == "(":

elif char == ")":#遇到了右括號,運算子出棧到postfix中,並且將左括號出棧

while stack[-1]!="(":

stack.pop()

elif operator_precedence[char] > operator_precedence[stack[-1]]:

#只要優先順序數字大,那麼就繼續追加

else:

while len(stack)!=0:

if stack[-1]=="(":#運算子棧一直出棧,直到遇到了左括號或者長度為0

break

while len(stack)!=0:#如果符號站裡面還有元素,就直接將其出棧到表示式棧裡面

return postfix

#*************************==這部分用於構造表示式樹,不涉及計算******************************==#

class node(object):

def __init__(self, val):

self.val = val

self.left = none

self.right = none

def create_expression_tree(postfix):

"""利用字尾表示式,構造二叉樹

"""stack =

#print postfix

for char in postfix:

if char not in operator_precedence:

#非操作符,即葉子節點

node = node(char)

else:

#遇到了運算子,出兩個,進乙個。

node = node(char)

right = stack.pop()

left = stack.pop()

node.right = right

node.left = left

#將最後乙個出了即可。

return stack.pop()

def inorder(tree):

if tree:

inorder(tree.left)

print tree.val

inorder(tree.right)

#*************************====這部分用於計算值***********************************#

def calculate(num1, op, num2):

if not num1.isdigit() and not num2.isdigit():

raise "num error"

else:

num1 = int(num1)

num2 = int(num2)

if op == "+":

return num1 + num2

elif op == "-":

return num1 - num2

elif op == "*":

return num1 * num2

elif op == "/":

if num2==0:

raise "zeros error"

else:

return num1/num2

else:

raise "op error"

def cal_expression_tree(postfix):

stack =

for char in postfix:

if char in "+-*/":

op = stack.pop()

num2 = stack.pop()

num1 = stack.pop()

value = calculate(num1, op, num2)

value = str(value)#計算結果是數值型別,將其化為字串型別

return int(stack[0])

if __name__=="__main__":

#另外異常情況的判斷的話,可以使用try catch

exp = "1+2*(3-1)-4"

postfix = postfix_convert(exp)

#print "postfix:",postfix

#tree = create_expression_tree(postfix)

#inorder(tree)

print cal_expression_tree(postfix)

首先,運算子的優先順序的定義operator_precedence字典的定義比較重要。遇到了(3-1*2)與(3*1-1)這兩種情況,對三種運算子的優先順序左右括號、減號、乘號,就不能簡單的出棧進棧進行運算了。

其次,postfix_convert()函式將字串表示式化為字尾表示式是關鍵。

最後,對於異常情況的處理,可以使用try catch,或者提前判斷,這裡在calculate()函式裡面做了些判斷。

主要參考:

expression tree

《資料結構與高分筆記》p132

順序堆疊應用--表示式計算

shell 字串 表示式

在shell程式設計中,經常要處理一些字串變數。比如,計算長度啊 擷取子串啊 字元替換啊等等,常常要用到awk expr sed tr等命令。下面給大家介紹個簡單的字串處理方法,用不著巢狀複雜的子命令。計算value字串的字元數量。或 刪除value字串中以分隔符 匹配的右邊字元,保留左邊字元。或 ...

字串 表示式求值

不曾想到我居然還會寫這種部落格,然而自己是真的對這些模擬很噁心。這簡單,可以遞迴求解,遇到乙個符號,直接往下遞迴。這裡我的處理是有空格的,因此呢可以使用atof將字串轉化了double,atoi好像是轉化為int。include include include include include inc...

Python 字串與正規表示式

alist list range 1 1001 blist list map str alist cstr join blist dstr cstr str sum range 1 1001 print dstr open text.txt w write dstr import os print ...