python輸入數學表達式并求值_用Python3實現表達式求值

一、題目描述

請用 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,此文發布時,這門課剛剛在 “學堂在線” 上開課兩天】

用 Python3 實現,初看一下,首先想到的其實是一種“討巧”(作弊 >_<)的方法(由于曾經網站被掛碼的悲壯歷史……),即通過 eval() 函數(這應該是黑客用得最多的一個函數了吧+_+)直接求解表達式,誰叫題目指定用 Python 這種方便的腳本語言呢~

大致代碼區區幾行:

1 from sys importargv2

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 importargv15 from decimal import *

16

17 defdelBlank(str):18 """

19 Delete all blanks in the str20 """

21 ans = ""

22 for e instr:23 if e != " ":24 ans +=e25 returnans26

27 defprecede(a, b):28 """

29 Compare the prior of operator a and b30 """

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 returnprior[char2num[a]][char2num[b]]57

58 defoperate(a, b, operator):59 """

60 Operate [a operator b]61 """

62 if operator == '+':63 ans = a +b64 elif operator == '-':65 ans = a -b66 elif operator == '*':67 ans = a *b68 elif operator == '/':69 if b ==0:70 ans = "VALUE ERROR"

71 else:72 ans = a /b73 elif operator == '^':74 if a == 0 and b ==0:75 ans = "VALUE ERROR"

76 else:77 ans = a **b78

79 returnans80

81 defcalc(exp):82 """

83 Calculate the ans of exp84 """

85 exp += '#'

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

87 stackOfOperator, stackOfNum = ['#'], []88 pos, ans, index, length =0, 0, 0, len(exp)89 while index

<

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/538990.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/538990.shtml
英文地址,請注明出處:http://en.pswp.cn/news/538990.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

mac上的mysql管理工具sequel pro

https://blog.csdn.net/wan_zaiyunduan/article/details/54909389 以前用過Plsql、Navicat、Workbench&#xff0c;現在換到mac上&#xff0c;用了現在這一款管理工具&#xff0c;很好用&#xff0c;所以推薦給大家。 完整的MySQL支持 Sequel Pro是一個快速,易于使用的Mac數據庫…

報錯 classes 拒絕訪問_3種方式“移除”快速訪問;為什么移除?你懂的...

Windows 10 在文件資源管理器中引入了"快速訪問"這個功能&#xff0c;每當打開文件資源管理器窗口時&#xff0c;您都會看到常用文件夾和最近訪問的文件的列表&#xff0c;這個功能雖然方便了日常使用&#xff0c;可能會提高工作效率&#xff0c;但是如果是公司的電腦…

java set是重復_java算法題,set內出現重復元素

題目將數字 1…9 填入一個33 的九宮格中&#xff0c;使得格子中每一橫行和的值全部相等&#xff0c;每一豎列和的值全部相等。請你計算有多少種填數字的方案。這個是計蒜客上面的一個模擬題&#xff0c;我采用暴力。public class _3 {/** 將數字 1…9 填入一個33 的九宮格中&am…

Lock的lockInterruptibly()

概述 lockInterruptibly()方法比較特殊&#xff0c;當通過這個方法去獲取鎖時&#xff0c;如果其他線程正在等待獲取鎖&#xff0c;則這個線程能夠響應中斷&#xff0c;即中斷線程的等待狀態。也就使說&#xff0c;當兩個線程同時通過lock.lockInterruptibly()想獲取某個鎖時&…

python中把輸出結果寫到一個文件中_Python3.6筆記之將程序運行結果輸出到文件的方法...

Python3.6筆記之將程序運行結果輸出到文件的方法 更新時間&#xff1a;2018年04月22日 14:27:32 投稿&#xff1a;jingxian 下面小編就為大家分享一篇Python3.6筆記之將程序運行結果輸出到文件的方法&#xff0c;具有很好的參考價值&#xff0c;希望對大家有所幫助。一起跟隨小…

hangfire.mysql.core_abp 使用 hangfire結合mysql

abp 官方使用的hangfire 默認使用的是sqlserver的存儲mysql須要引入支持mysql的類庫sql我這邊使用的是Hangfire.MySql.Core數據庫直接用nuget安裝便可app首先按照官方文檔要求&#xff0c;改幾個地方sqlserver分別是 Startup 文件下serverservices.AddHangfire(config >{con…

python 圖標題上移_Python-Matplotlib將圖形標題移動到y軸

我目前在python中使用matplotlib來繪制一些數據,但是我希望圖表的標題位于Y軸上,因為沒有足夠的空間來存儲一個圖形的標題和另一個圖形的x軸標簽.我知道我可以將hspace設置為更大的數字但是,我不想這樣做,因為我計劃將幾個圖表堆疊在一起,如果我調整hspace,那么圖表將是真的簡短…

solr的基礎使用

查詢運算符 例如&#xff1a;http://localhost:8984/solr/mycore/select?q*:* : 指定字段查指定值&#xff0c;如返回所有值q*:* ? 匹配單個字符&#xff0c; 例如: qtitle:??拳 可以匹配標題為“形意拳”的文檔 * 匹配零個或多個字符, 例如: qtitle:*形意拳 或者 qtitl…

同步關鍵詞lock

概述 1、API在JDK的java.util.concurrent.locks下。 2、不是Java關鍵字&#xff0c;是接口。 3、ReentrantLock是JDK唯一實現了Lock接口的類。 public interface Lock {//獲取鎖void lock();//可以響應中斷的鎖void lockInterruptibly() throws InterruptedException;//嘗試…

Java bitset轉string_將java BitSet保存到DB

默認情況下,JPA使用Java序列化來保存未知Serializable類型的屬性(以便將序列化表示存儲為byte []).通常它不是您想要的,因為可以有更有效的方式來表示您的數據.例如,BitSet可以有效地表示為數字(如果它的大小有界),或者byte [],或其他東西(遺憾的是,BitSet不提供進行這些轉換的…

python讀取raw圖片文件_在python下讀取并展示raw格式的圖片實例

raw文件可能有些人沒有&#xff0c;因此&#xff0c;先用一張圖片創建一個raw格式的文件&#xff08;其實可以是其他類型的格式文件&#xff09; import numpy as np import cv2 img cv2.imread(cat.jpg) # 這里需要我們在當前目錄下放一張名為cat.jpg的文件 img.tofile(cat.r…

python怎么網絡通信_深入Python中的網絡通信

TCP/IP計算機與網絡設備兩情侶要談戀愛&#xff0c;相互通信&#xff0c;那么雙方就必須有規則。基于相同的方法&#xff0c;不同的硬件、操作系統之間的通信&#xff0c;都需要一種規則。而我們就把這種規則稱為協議(protocol)。TCP/IP 是互聯網相關各類協議族的總稱。TCP/IP是…

ReadWriteLock讀寫文件

概述 ReadWriteLock是一個接口&#xff0c;在它里面只定義了兩個方法&#xff1a;一個讀的鎖和一個寫的鎖。 讀的鎖&#xff1a;A線程獲取了讀的鎖&#xff0c;那么B線程也可以獲取讀的鎖。 寫的鎖&#xff1a;A線程獲取了寫的鎖&#xff0c;那么B線程不能獲取讀也不能獲取寫…

搞懂 Java HashMap 源碼

HashMap 源碼分析 前幾篇分析了 ArrayList &#xff0c; LinkedList &#xff0c;Vector &#xff0c;Stack List 集合的源碼&#xff0c;Java 容器除了包含 List 集合外還包含著 Set 和 Map 兩個重要的集合類型。而 HashMap 則是最具有代表性的&#xff0c;也是我們最常使用到…

python 怎么表示sqlserver null_如何使用Python將sqlserver查詢輸出寫入.txt文件?

我是Python新手&#xff0c;嘗試連接到sqlserverdb并將查詢的輸出轉換成一個flat.txt文件。在一些代碼正在工作&#xff0c;但是只寫了將近1000條記錄&#xff0c;然后就停止了。在Python版本&#xff1a;2.7.13。在下面的代碼能夠把100萬條記錄全部寫入csv文件而不是.txt文件&…

python中object是什么類型_Python 的 type 和 object 之間是怎么一種關系?

class&#xff0c;metaclass&#xff0c;instance&#xff0c;subclass&#xff0c;base 以下成立&#xff1a; 對任意的A&#xff0c;A是instance&#xff08;推論&#xff1a;任意class也是instance&#xff09; 對任意A&#xff0c;存在B&#xff0c;使得B是A的class A是cla…

java8新生代_jdk8.0的jvm詳情

jstat命令可以查看堆內存各部分的使用量&#xff0c;以及加載類的數量。命令的格式如下&#xff1a;jstat [-命令選項] [vmid] [間隔時間/毫秒] [查詢次數]注意&#xff1a;使用的jdk版本是jdk8.[work16-11-118qf-pms]$ jstat -class 32417Loaded?? Bytes?? Unloaded?? B…

Java中的Runnable、Callable、Future、FutureTask的區別與示例

原文地址&#xff1a;http://blog.csdn.net/bboyfeiyu/article/details/24851847 --------------------------------------------------------- Java中存在Runnable、Callable、Future、FutureTask這幾個與線程相關的類或者接口&#xff0c;在Java中也是比較重要的幾個概念&am…

sql count為空時顯示0_C0010負坐標顯示為正數+紅色0值參考線

小伙伴們早上好啊&#xff01;今天繼續為大家分享柱形圖的美化技巧。希望大家認真閱讀Excel文件和教程&#xff0c;有的圖表看起來簡單&#xff0c;實際上在細節處理上用了很多技巧&#xff0c;大家要多多體會。C0010-負坐標顯示為正數紅色0值參考線效果圖圖表概述本圖可以用來…

配置IISExpress允許外部訪問

配置IISExpress允許外部訪問 1.找到IISExpress的配置文件&#xff0c;位于 <文檔>/IISExpress/config文件夾下&#xff0c;打開applicationhost.config&#xff0c;找到如下代碼&#xff1a;<site name"WebSite1" id"1" serverAutoStart"tru…