日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

用python编写表达式求值_用Python3实现表达式求值

發布時間:2023/12/10 python 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用python编写表达式求值_用Python3实现表达式求值 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Problem Description yizhen has no girlfriend due to his stupid brain that he even can’t solve a simple arithmetic roblem. Can you help him If you solve it and tell him the result, then he can find his lovers! So beautiful! Input The input

一、題目描述

請用 python3編寫一個計算器的控制臺程序,支持加減乘除、乘方、括號、小數點,運算符優先級為括號>乘方>乘除>加減,同級別運算按照從左向右的順序計算。

二、輸入描述

數字包括"0123456789",小數點為".",運算符包括:加("+")、減("-")、乘("*")、除("/")、乘方("^",注:不是**!)、括號("()")

需要從命令行參數讀入輸入,例如提交文件為 main.py,可以用 python3?main.py "1+2-3+4" 的方式進行調用

輸入需要支持空格,即?python3?main.py "1 ? ? + ? ? 2 ? ? ?- ? ? 3 ? ?+ ? ?4" 也需要程序能夠正確給出結果

所有測試用例中參與運算的非零運算數的絕對值范圍保證在 10^9-10^(-10) 之內, 應該輸出運算結果時非零運算結果絕對值也保證在該范圍內

三、輸出描述

數字需要支持小數點,輸出結果取10位有效數字,有效數字位數不足時不能補0

對于不在輸入描述內的輸入,輸出INPUT ERROR

對于格式不合法(例如括號不匹配等)的輸入,輸出 FORMAT ERROR

對于不符合運算符接收的參數范圍(例如除0等)的輸入,輸出VALUE ERROR

對于2、3、4的情況,輸出即可,不能拋出異常

同時滿足2、3、4中多個條件時,以序號小的為準

四、樣例

輸入: 1 + 2 - 3 + 4

輸出: 4

輸入: 1 + 2 - 3 + 1 / 3

輸出: 0.3333333333

輸入: 1 + + 2

輸出: FORMAT ERROR

輸入: 1 / 0

輸出: VALUE ERROR

輸入: a + 1

輸出: INPUT ERROR

【注:此題為TsinghuaX:34100325X 《軟件工程》 MOOC 課程 Spring, 2016 Chapter 1 Problem,此文發布時,這門課剛剛在 “學堂在線” 上開課兩天】

代碼是先看了 http://blog.csdn.net/whos2002110/article/details/19119449 這個網址的。然后 自己記憶寫了一份。 本來目的是要學一些 解釋器的。雖然也看到一些實現,但是感覺對我有點難度,于是從簡單開始學習。 import java.util.ArrayList;import java.

用 Python3 實現,初看一下,首先想到的其實是一種“討巧”(作弊 >_

大致代碼區區幾行:

1 from sys import argv

2

3 if __name__ == "__main__":

4 exp = argv[1]

5 print(eval(exp))

即便是考慮到題干中的輸出要求做異常處理(try...except)輸出相應的錯誤信息,也就十行左右。

但稍深入就會發現,有些情形還是無法按要求處理的,比如樣例 “1 + + 2”,用 eval() 會輸出結果 “3” (+2 前的 “+” 被當作正號),而題目要求輸出 “FORMAT ERROR”。

沒辦法,只能老老實實做苦力活兒了。

表達式求值其實是《數據結構》課程里一個基本且重要的問題之一,一般作為 “棧” 的應用來提出。

問題的關鍵就是需要按照人們通常理解的運算符的優先級來進行計算,而在計算過程中的臨時結果則用 棧 來存儲。

為此,我們可以首先構造一個 “表” 來存儲當不同的運算符 “相遇” 時,它們誰更 “屌” 一些(優先級更高一些)。這樣就可以告訴計算機,面對不同的情形,它接下來應該如何來處理。

其次,我們需要構造兩個棧,一個運算符棧,一個運算數棧。

運算符棧是為了搞定當某個運算符優先級較低時,暫時先讓它呆在棧的底部位置,待它可以 “重見天日” 的那一天(優先級相對較高時),再把它拿出來使用。正確計算完成后,此棧應為空。

運算數棧則是為了按合理的計算順序存儲運算中間結果。正確計算完成后,此棧應只剩下一個數,即為最后的結果。

完整的代碼如下:

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

2

3 #################################

4 # @Author: Maples7

5 # @LaunchTime: 2016/2/24 12:32:38

6 # @FileName: main

7 # @Email: maples7@163.com

8 # @Function:

9 #

10 # A Python Calculator for Operator +-*/()^

11 #

12 #################################

13

14 from sys import argv

15 from decimal import *

16

17 def delBlank(str):

18 """

19 Delete all blanks in the str

20 """

21 ans = ""

22 for e in str:

23 if e != " ":

24 ans += e

25 return ans

26

27 def precede(a, b):

28 """

29 Compare the prior of operator a and b

30 """

31 # the prior of operator

32 prior = (

33 # '+' '-' '*' '/' '(' ')' '^' '#'

34 ('>', '>', '', ''), # '+'

35 ('>', '>', '', ''), # '-'

36 ('>', '>', '>', '>', '', ''), # '*'

37 ('>', '>', '>', '>', '', ''), # '/'

38 ('

39 ('>', '>', '>', '>', ' ', '>', '>', '>'), # ')'

40 ('>', '>', '>', '>', '', '>', '>'), # '^'

41 ('

42 )

43

44 # operator to index of prior[8][8]

45 char2num = {

46 '+': 0,

47 '-': 1,

48 '*': 2,

49 '/': 3,

50 '(': 4,

51 ')': 5,

52 '^': 6,

53 '#': 7

54 }

55

56 return prior[char2num[a]][char2num[b]]

57

58 def operate(a, b, operator):

59 """

60 Operate [a operator b]

61 """

62 if operator == '+':

63 ans = a + b

64 elif operator == '-':

65 ans = a - b

66 elif operator == '*':

67 ans = a * b

68 elif operator == '/':

69 if b == 0:

70 ans = "VALUE ERROR"

71 else:

72 ans = a / b

73 elif operator == '^':

74 if a == 0 and b == 0:

75 ans = "VALUE ERROR"

76 else:

77 ans = a ** b

78

79 return ans

80

81 def calc(exp):

82 """

83 Calculate the ans of exp

84 """

85 exp += '#'

86 operSet = "+-*/^()#"

87 stackOfOperator, stackOfNum = ['#'], []

88 pos, ans, index, length = 0, 0, 0, len(exp)

89 while index < length:

90 e = exp[index]

91 if e in operSet:

92 # calc according to the prior

93 topOperator = stackOfOperator.pop()

94 compare = precede(topOperator, e)

95 if compare == '>':

96 try:

97 b = stackOfNum.pop()

98 a = stackOfNum.pop()

99 except:

100 return "FORMAT ERROR"

101 ans = operate(a, b, topOperator)

102 if ans == "VALUE ERROR":

103 return ans

104 else:

105 stackOfNum.append(ans)

106 elif compare == '

107 stackOfOperator.append(topOperator)

108 stackOfOperator.append(e)

109 index += 1

110 elif compare == '=':

111 index += 1

112 elif compare == ' ':

113 return "FORMAT ERROR"

114 else:

115 # get the next num

116 pos = index

117 while not exp[index] in operSet:

118 index += 1

119 temp = exp[pos:index]

120

121 # delete all 0 of float in the end

122 last = index - 1

123 if '.' in temp:

124 while exp[last] == '0':

125 last -= 1

126 temp = exp[pos:last + 1]

127

128 try:

129 temp = Decimal(temp)

130 except:

131 return "INPUT ERROR"

132 stackOfNum.append(temp)

133

134 if len(stackOfNum) == 1 and stackOfOperator == []:

135 return stackOfNum.pop()

136 else:

137 return "INPUT ERROR"

138

139 if __name__ == "__main__":

140 # get the exp

141 exp = argv[1]

142

143 # set the precision

144 getcontext().prec = 10

145

146 # delete blanks

147 exp = delBlank(exp)

148

149 # calc and print the ans

150 ans = calc(exp)

151 print(ans)

其中需要稍微注意的細節有:

1. 表達式處理前,前后都插入一個 '#' 作為一個特殊的運算符,這樣做是為了方便統一處理,即不用再去特別判斷表達式是否已經結束(從而引發一系列邊界問題導致代碼冗長復雜,這種處理也可稱之為 “哨兵” 技巧)。如果最后兩個運算符相遇則說明表達式處理完畢,這個運算符的優先級也是最低的(在 prior 表中也有體現)。

2. 輸出要求比較復雜,拋去錯誤信息輸出不說(只能具體情況具體分析),不能輸出多余的0,折騰了一會兒最后發現用高精度的?Decimal 可以完美滿足題目要求。

3. 由于不能輸出多余的0,所以在帶有小數部分的數字 “錄入” 時(代碼115-132行),就要把一些多余的0提前去掉(代碼121-126行),比如 2.0 這樣的情況。

總結

以上是生活随笔為你收集整理的用python编写表达式求值_用Python3实现表达式求值的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。