使用python從三個(gè)角度解決josephus問(wèn)題的方法
0 寫在前面
josephus問(wèn)題是數(shù)據(jù)結(jié)構(gòu)教材中的一個(gè)常見實(shí)例,其問(wèn)題可以描述為:
設(shè)nnn個(gè)人圍坐一圈,現(xiàn)在要求從第kkk個(gè)人開始報(bào)數(shù),報(bào)到第mmm個(gè)的人退出。然后從下一個(gè)人開始繼續(xù)按照同樣規(guī)則報(bào)數(shù)并退出,直到所有人退出為止。要求按照順序輸出每個(gè)人的序列號(hào)。
1 基于數(shù)組概念的解法
首先考慮基于python的list和固定大小的數(shù)組概念,即將list看作元素個(gè)數(shù)固定的對(duì)象,只改變值而不刪除元素,相當(dāng)于擺了一圈nnn把椅子,人雖然退出但是椅子還在,我們可以給每個(gè)人從111到nnn編號(hào),沒有人的位置用000表示,思路如下:
初始
- 建立包含nnn個(gè)人(編號(hào))的list
- 找到第kkk個(gè)人開始
運(yùn)行
- 從kkk的位置開始數(shù)到mmm,中間遇到000的就跳過(guò)
- 數(shù)到mmm之后,將其值改為000
- 然后繼續(xù)循環(huán),總共循環(huán)nnn次(因?yàn)槊看窝h(huán)就會(huì)退出一個(gè)人)
代碼如下:
def josephus_A(n, k, m): people = list(range(1, (n+1))) i = k-1 for num in range(n): count = 0 while count < m: if people[i] > 0: count += 1 if count == m: print(people[i], end=" ") people[i] = 0 i = (i+1) % n # count只是flag,真正記的數(shù)是i if num < n-1: print(end=",", ) else: print(" ")
2 基于順序表的解法
順序表是線性表的一種,即表中元素放在一塊足夠大的連續(xù)存儲(chǔ)區(qū)里,首元素存入存儲(chǔ)區(qū)開始位置,其余元素依次存放。順序表在python中的也是list,跟第一種解法不同,當(dāng)?shù)趍mm個(gè)人退出需要進(jìn)行刪除元素的操作,才是順序表。而第一種解法的數(shù)組想要?jiǎng)h除并不是那么容易,這里是因?yàn)閜ython中沒有內(nèi)置對(duì)數(shù)組的支持,所以用list代替,具體可以參照c++中的數(shù)組,如果要?jiǎng)h除中間的某個(gè)元素的話,必須對(duì)后面的元素重新編號(hào)。代碼實(shí)現(xiàn)如下:
def josephus_L(n, k, m): people = list(range(1, (n+1))) i=k-1 for num in range(n,0,-1): i=(i+m-1)%num print(people.pop(i),end=", " if num>1 else "\n")
3 基于循環(huán)單鏈表的解法
單鏈表即單向鏈接表,典型的就是c++中的鏈表,循環(huán)單鏈表就是頭尾相連的單鏈表,也是線性表的一種,這道題目使用循環(huán)單鏈表記錄nnn個(gè)人圍坐一圈最為契合。我們只需要數(shù)到第mmm個(gè)結(jié)點(diǎn)就刪除,刪除操作對(duì)于鏈表來(lái)說(shuō)比較容易,而且不需要有i = (i+1) % n這樣的整除操作。但是問(wèn)題在于python并沒有像c++那樣有內(nèi)置對(duì)鏈表的支持,因此需要建立一個(gè)鏈表的類,建立是比較麻煩的,但是操作比較簡(jiǎn)單,如下:
class LNode: # 建立鏈表結(jié)點(diǎn) def __init__(self,elem,next_=None): self.elem=elem self.next=next_ class LCList: # 建立循環(huán)鏈接表 def __init__(self): self._rear=None def is_empty(self): return self._rear is None def prepend(self,elem): # 前端插入 p=LNode(elem) if self._rear is None: p.next=p # 建立一個(gè)結(jié)點(diǎn)的環(huán) self._rear=p else: p.next=self._rear.next self._rear.next=p def append(self,elem): # 尾端插入 self.prepend(elem) self._rear = self._rear.next def pop(self): # 前端彈出 if self._rear is None: raise LinkedListUnderflow("in pop of CLList") p = self._rear.next if self._rear is p: self._rear =None else: self._rear.next=p.next return p.elem def printall(self): # 輸出表元素 if self.is_empty(): return p = self._rear.next while True: print(p.elem) if p is self._rear: break p=p.next class LinkedListUnderflow(ValueError): # 自定義異常 pass class Josephus(LCList): def __init__(self,n,k,m): LCList.__init__(self) for i in range(n): self.append(i+1) self.turn(k-1) while not self.is_empty(): self.turn(m-1) print(self.pop(),end=("\n" if self.is_empty() else ", ")) def turn(self,m): for i in range(m): self._rear = self._rear.next
到此這篇關(guān)于使用python從三個(gè)角度解決josephus問(wèn)題的方法的文章就介紹到這了,更多相關(guān)python josephus問(wèn)題內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python面向?qū)ο蟪绦蛟O(shè)計(jì)類變量與成員變量、類方法與成員方法用法分析
這篇文章主要介紹了Python面向?qū)ο蟪绦蛟O(shè)計(jì)類變量與成員變量、類方法與成員方法用法,結(jié)合實(shí)例形式較為詳細(xì)的分析了類變量與成員變量、類方法與成員方法、類方法與靜態(tài)方法等概念、原理及使用技巧,需要的朋友可以參考下2019-04-04用Python代碼自動(dòng)生成文獻(xiàn)的IEEE引用格式的實(shí)現(xiàn)
這篇文章主要介紹了用Python代碼自動(dòng)生成文獻(xiàn)的IEEE引用格式的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03python grpc實(shí)現(xiàn)異步調(diào)用(不用grpc異步接口)
grpc同步調(diào)用更簡(jiǎn)單,但是在處理復(fù)雜任務(wù)時(shí),會(huì)導(dǎo)致請(qǐng)求阻塞,影響吞吐,本文主要介紹了python grpc實(shí)現(xiàn)異步調(diào)用,不用grpc異步接口,具有一定的參考價(jià)值,感興趣的可以了解一下2024-04-04python實(shí)現(xiàn)讀取類別頻數(shù)數(shù)據(jù)畫水平條形圖案例
這篇文章主要介紹了python實(shí)現(xiàn)讀取類別頻數(shù)數(shù)據(jù)畫水平條形圖案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04使用python畫出邏輯斯蒂映射(logistic map)中的分叉圖案例
這篇文章主要介紹了使用python畫出邏輯斯蒂映射(logistic map)中的分叉圖案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12Python網(wǎng)絡(luò)爬蟲出現(xiàn)亂碼問(wèn)題的解決方法
這篇文章主要為大家詳細(xì)介紹了Python網(wǎng)絡(luò)爬蟲出現(xiàn)亂碼問(wèn)題的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01將python文件打包exe獨(dú)立運(yùn)行程序方法詳解
這篇文章主要介紹了將python文件打包exe獨(dú)立運(yùn)行程序方法詳解,需要的朋友可以參考下2020-02-02