1. 程式人生 > >Python演算法實戰系列之棧

Python演算法實戰系列之棧

棧(stack)又稱之為堆疊是一個特殊的有序表,其插入和刪除操作都在棧頂進行操作,並且按照先進後出,後進先出的規則進行運作。

如下圖所示

例如槍的彈匣,第一顆放進彈匣的子彈反而在發射出去的時候是最後一個,而最後放入彈匣的一顆子彈在打出去的時候是第一顆發射出去的。

棧的介面

如果你建立了一個棧,那麼那麼應該具有以下介面來進行對棧的操作

介面 描述
push() 入棧
pop() 出棧
isEmpty() 判斷是否為空棧
length() 獲取棧的長度
getTop() 取棧頂的元素,元素不出棧

知道棧需要上述的介面後,那麼在Python中,列表就類似是一個棧,提供介面如下:

操作 描述
s = [] 建立一個棧
s.append(x) 往棧內新增一個元素
s.pop() 在棧內刪除一個元素
not s 判斷是否為空棧
len(s) 獲取棧內元素的數量
s[-1] 獲取棧頂的元素

Python中的棧介面使用例項:

Python
12345678910111213141516171819202122232425 # 建立一個棧In[1]:s=[]# 往棧內新增一個元素In[2]:s.append(1)In[3]:sOut[3]:[1]# 刪除棧內的一個元素In[4]:s.pop()Out[4]:1In[5]:sOut[5]:[]# 判斷棧是否為空In[6]:notsOut[6]:TrueIn[7]:s.append(1)In[8]:notsOut[8]:False# 獲取棧內元素的數量In[9]:len(s)Out[9]:1In[10]:
s.append(2)In[11]:s.append(3)# 取棧頂的元素In[12]:s[-1]Out[12]:3

一大波例項

在瞭解棧的基本概念之後,讓我們再來看幾個例項,以便於理解棧。

括號匹配

題目

假如表示式中允許包含三中括號()[]{},其巢狀順序是任意的,例如:

正確的格式

Python
1 {()[()]},[{({})}]

錯誤的格式

Python
1 [(]),[()),(()}

編寫一個函式,判斷一個表示式字串,括號匹配是否正確

思路

  1. 建立一個空棧,用來儲存尚未找到的左括號;
  2. 便利字串,遇到左括號則壓棧,遇到右括號則出棧一個左括號進行匹配;
  3. 在第二步驟過程中,如果空棧情況下遇到右括號,說明缺少左括號,不匹配;
  4. 在第二步驟遍歷結束時,棧不為空,說明缺少右括號,不匹配;

解決程式碼

建議在pycharm中打斷點,以便於更好的理解

Python
12345678910111213141516171819202122 #!/use/bin/env python# _*_ coding:utf-8 _*_LEFT={'(','[','{'}# 左括號RIGHT={')',']','}'}# 右括號defmatch(expr):"""    :param expr:  傳過來的字串    :return:  返回是否是正確的    """stack=[]# 建立一個棧forbrackets inexpr:# 迭代傳過來的所有字串ifbrackets inLEFT:# 如果當前字元在左括號內stack.append(brackets)# 把當前左括號入棧elifbrackets inRIGHT:# 如果是右括號ifnotstack ornot1<=ord(brackets)-ord(stack[-1])<=2:# 如果當前棧為空,()]# 如果右括號減去左括號的值不是小於等於2大於等於1returnFalse# 返回Falsestack.pop()# 刪除左括號returnnotstack# 如果棧內沒有值則返回True,否則返回Falseresult=match('[(){()}]')print(result)

迷宮問題

題目

用一個二維陣列表示一個簡單的迷宮,用0表示通路,用1表示阻斷,老鼠在每個點上可以移動相鄰的東南西北四個點,設計一個演算法,模擬老鼠走迷宮,找到從入口到出口的一條路徑。

如圖所示

出去的正確線路如圖中的紅線所示

思路

  1. 用一個棧來記錄老鼠從入口到出口的路徑
  2. 走到某點後,將該點左邊壓棧,並把該點值置為1,表示走過了;
  3. 從臨近的四個點中可到達的點中任意選取一個,走到該點;
  4. 如果在到達某點後臨近的4個點都不走,說明已經走入死衚衕,此時退棧,退回一步嘗試其他點;
  5. 反覆執行第二、三、四步驟直到找到出口;

解決程式碼

Python
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 #!/use/bin/env python# _*_ coding:utf-8 _*_definitMaze():"""    :return: 初始化迷宮    """maze=[[0]*7for_inrange(5+2)]# 用列表解析建立一個7*7的二維陣列,為了確保迷宮四周都是牆walls=[# 記錄了牆的位置(1,3),(2,1),(2,5),(3,3),(3,4),(4,2),# (4, 3),  # 如果把(4, 3)點也設定為牆,那麼整個迷宮是走不出去的,所以會返回一個空列表(5,4)]foriinrange(7):# 把迷宮的四周設定成牆maze[i][0]=maze[i][-1]=1maze[0][i]=maze[-1][i]=1fori,jinwalls:# 把所有牆的點設定為1maze[i][j]=1returnmaze"""[1, 1, 1, 1, 1, 1, 1][1, 0, 0, 1, 0, 0, 1][1, 1, 0, 0, 0, 1, 1][1, 0, 0, 1, 1, 0, 1][1, 0, 1, 0, 0, 0, 1][1, 0, 0, 0, 1, 0, 1][1, 1, 1, 1, 1, 1, 1]"""defpath(maze,start,end):"""    :param maze: 迷宮    :param start: 起始點    :param end: 結束點    :return: 行走的每個點    """i,j=start# 分解起始點的座標ei,ej=end# 分解結束點的左邊stack=[(i,j)]# 建立一個棧,並讓老鼠站到起始點的位置maze[i][j]=1# 走過的路置為1whilestack:# 棧不為空的時候繼續走,否則退出i,j=stack[-1]# 獲取當前老鼠所站的位置點if(i,j)==(ei,ej):break# 如果老鼠找到了出口fordi,dj in[(0,-1),(0,1),(-1,0),(1,0)]:# 左右上下ifmaze[i+di][j+dj]==0:# 如果當前點可走maze[i+di][j+dj]=1# 把當前點置為1stack.append((i+di,j+dj))# 把當前的位置新增到棧裡面breakelse:# 如果所有的點都不可走stack.pop()# 退回上一步returnstack# 如果迷宮不能走則返回空棧Maze=initMaze()# 初始化迷宮result=path(maze=Maze,start=(1,1),end=(5,5))# 老鼠開始走迷宮print(result)# [(1, 1), (1, 2), (2, 2), (3, 2), (3, 1), (4, 1), (5, 1), (5, 2), (5, 3), (4, 3), (4, 4), (4, 5), (5, 5)]

字尾表示式求值

題目

計算一個表示式時,編譯器通常使用字尾表示式,這種表示式不需要括號:

中綴表示式 字尾表示式
2 + 3 * 4 2 3 4 * +
( 1 + 2 ) * ( 6 / 3 ) + 2 1 2 + 6 3 / * 2 +
18 / ( 3 * ( 1 + 2 ) ) 18 3 1 2 + * /

編寫程式實現字尾表示式求值函式。

思路

  1. 建立一個棧來儲存待計算的運算元;
  2. 遍歷字串,遇到運算元則壓入棧中,遇到操作符號則出棧運算元(n次),進行相應的計算,計算結果是新的運算元壓回棧中,等待計算
  3. 按上述過程,遍歷完整個表示式,棧中只剩下最終結果;

解決程式碼

Python
123456789101112131415161718192021222324252627 #!/use/bin/env python# _*_ coding:utf-8 _*_operators={# 運算子操作表'+':lambdaop1,op2:op1+op2,'-':lambdaop1,op2:op1-op2,'*':lambdaop1,op2:op1*op2,'/':lambdaop1,op2:op1/op2,}defevalPostfix(e):"""    :param e: 字尾表示式    :return: 正常情況下棧內的第一個元素就是計算好之後的值    """tokens=e.split()# 把傳過來的字尾表示式切分成列表stack=[]fortokenintokens:# 迭代列表中的元素iftoken.isdigit():# 如果當前元素是數字stack.append(int(token))# 就追加到棧裡邊eliftokeninoperators.keys

相關推薦

Python演算法實戰系列

棧(stack)又稱之為堆疊是一個特殊的有序表,其插入和刪除操作都在棧頂進行操作,並且按照先進後出,後進先出的規則進行運作。 如下圖所示 例如槍的彈匣,第一顆放進彈匣的子彈反而在發射出去的時候是最後一個,而最後放入彈匣的一顆子彈在打出去的時候是第一顆發射出去的。 棧的介面

Python演算法實戰系列佇列

佇列(queue),是先進先出(FIFO, First-In-First-Out)的線性表,在具體應用中通常用連結串列或者陣列來實現,佇列只允許在後端(稱為rear)進行插入操作,在前端(稱為front)進行刪除操作,佇列的操作方式和堆疊類似,唯一的區別在於佇列只允許新資料在後

Appium python自動化測試系列等待函數如何進行實戰(九)

可能 res path 定位 __file__ poll 9.1 慢慢 定義 ?9.1 等待函數的使用 9.1.1 為什麽要使用等待函數 我們在做自動化的時候很多時候都不是很順利,不是因為app的問題,我們的腳本也沒問題,但是很多時候都會報錯,比如一個頁面本來就有id為1的

演算法實戰系列兩數相加

給出兩個 非空 的連結串列用來表示兩個非負的整數。其中,它們各自的位數是按照 逆序 的方式儲存的,並且它們的每個節點只能儲存 一位 數字。 如果,我們將這兩個數相加起來,則會返回一個新的連結串列來表示它們的和。 您可以假設除了數

python初級實戰系列教程《一、爬蟲爬取網頁、圖片、音視訊》

python基礎知識可以到廖雪峰大佬的官網學習哦! 廖雪峰官網網址 學完python就開始我們的實戰吧!首先我們就來學習下python爬蟲 學習Python爬蟲,先是介紹一個最容易上手的庫urll

.NET Core加解密實戰系列——RSA非對稱加密演算法

![](https://img2020.cnblogs.com/blog/2029875/202006/2029875-20200612165254059-1754283874.png) --- [TOC] ## 簡介 加解密現狀,編寫此專案的背景: - 需要考慮系統環境相容性問題(Linux、Wi

.NET Core加解密實戰系列——訊息摘要與數字簽名演算法

![](https://img2020.cnblogs.com/blog/2029875/202006/2029875-20200629172528304-1596961448.png) --- [TOC] ## 簡介 加解密現狀,編寫此係列文章的背景: - 需要考慮系統環境相容性問題(Linux、W

.NET Core加解密實戰系列——對稱加密演算法

## 簡介 加解密現狀,編寫此係列文章的背景: - 需要考慮系統環境相容性問題(Linux、Windows) - 語言互通問題(如C#、Java等)(加解密本質上沒有語言之分,所以原則上不存在互通性問題) - 網上資料版本不一、或不全面 - .NET官方庫密碼演算法提供不全面,很難針對其他語言(Java)進

實戰系列 Node.js 玩轉 Java

liunx array github cal ddn 公眾 當前 eth pan 這些年以來,Node.js的興起,JavaScript已經從當年的“世界最被誤解的語言”變成了“世界最流行的語言”。且其發展之勢,從語言本身的進

Appium python自動化測試系列Capability介紹(五)

語言 路徑 pla apk 過程 5.1 基礎 針對 driver ?5.1 Capability介紹 5.1.1 什麽是Capability 在講capability之前大家是否還記得在講log時給大家看過的啟動時的日誌?在我們的整個啟動日誌中會出現一些配置信息,其實那些

Appium python自動化測試系列元素的定位(六)

keditor logs ren 匹配 4.4 contex 應用 需要 運用 ?6.1 常用定位方法講解 對象定位是自動化測試中很關鍵的一步,也可以說是最關鍵的一步,畢竟你對象都沒定位那麽你想操作也不行。所以本章節的知識我希望大家多動手去操作,不要僅僅只是書本上的知識,畢

Appium python自動化測試系列認識Appium(四)

ndt require 差異 make python自動化 復雜 appium launched interface ?4.1界面認識 在之前安裝appium的時候說過我們有兩種方法安裝,也就有兩種結果,一種是有界面的,一種是沒有界面的,首先我們先講一下有界面的,以及界面有

Appium python自動化測試系列appium環境搭建(二)

ftp 自動化 手動 文件 搭建環境 做到 安裝python reg 成員 ?2.1 基礎環境搭建 當我們學習新的一項技術開始基本都是從環境搭建開始,本書除了第一章節也是的,如果你連最基礎的環境都沒有那麽我們也沒必要去說太多,大概介紹一下: 1、因為appium是支持and

Appium python自動化測試系列Android UIAutomator終極定位(七)

提升 而已 log key find align 寫法 自己 簡單 android uiautomator text定位 可能有人不知道為什麽說android uiautomator是終極定位,而且android uiautomator和appium有什麽關系呢?如果之前

Appium python自動化測試系列使用HTMLTestRunner生成測試報告(十三)

like resizable mes 500px string padding code tip hid ?13.1 測試報告概述 13.1.1 測試報告的定義 在前面章節我們已經講了自動化基礎的很多東西,如果說掌握了,而且自己動手去練習了,我相信在一些初級的面試中是沒

Python練手系列--名片管理系統

完成 elif menu 顯示 log pytho lob pos app 列表或字典做全局變量在函數中調用可以不用加global # 用來存儲名片 card_infors = [] def print_menu(): """完成打印功能菜單""" p

Python學習筆記系列002:變量 註釋 輸入 輸出

練習題 命名 outer 計算機 鍵盤 -a 考題 onerror rac 導讀: 1.變量 2.字符編碼 3.註釋 4.輸出 5.輸入 6.縮進 7.報錯單詞釋義 8.代碼規範 基礎語法是任何語言的基礎,只有熟練掌握,才能靈活用語言,寫出高效、優美、簡潔的代碼。 Py

docker實戰系列快速刪除docker中的容器

停用 amp 快速 stop div 系列 全部 top pre 1、停用全部運行中的容器 docker stop $(docker ps -q) 2、刪除全部容器 docker rm $(docker ps -aq) 3.停用並刪除容器 docker stop

docker實戰系列docker 端口映射錯誤解決方法

zha ifconfig tps -i mon CP CA des col 錯誤: Error response from daemon: Cannot start container web: iptables failed: iptables -t nat -A DO

python數據結構

允許 obj 概念 函數 指標 size 堆棧 進棧 div 棧棧(stack),有些地方稱為堆棧,是一種容器,可存入數據元素、訪問元素、刪除元素,它的特點在於只能允許在容器的一端(稱為棧頂端指標,英語:top)進行加入數據(英語:push)和輸出數據(英語:pop)的運算