使用python從三個(gè)角度解決josephus問(wèn)題的方法
0 寫在前面
josephus問(wèn)題是數(shù)據(jù)結(jié)構(gòu)教材中的一個(gè)常見(jiàn)實(shí)例,其問(wèn)題可以描述為:
設(shè)nnn個(gè)人圍坐一圈,現(xiàn)在要求從第kkk個(gè)人開(kāi)始報(bào)數(shù),報(bào)到第mmm個(gè)的人退出。然后從下一個(gè)人開(kāi)始繼續(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),沒(méi)有人的位置用000表示,思路如下:
初始
- 建立包含nnn個(gè)人(編號(hào))的list
- 找到第kkk個(gè)人開(kāi)始
運(yùn)行
- 從kkk的位置開(kāi)始數(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ū)開(kāi)始位置,其余元素依次存放。順序表在python中的也是list,跟第一種解法不同,當(dāng)?shù)趍mm個(gè)人退出需要進(jìn)行刪除元素的操作,才是順序表。而第一種解法的數(shù)組想要?jiǎng)h除并不是那么容易,這里是因?yàn)閜ython中沒(méi)有內(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并沒(méi)有像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)文章
django authenticate用戶身份認(rèn)證的項(xiàng)目實(shí)踐
Django的contrib.auth模塊中的authenticate()函數(shù)用于對(duì)用戶的憑據(jù)進(jìn)行身份驗(yàn)證,本文就來(lái)介紹一下django authenticate用戶身份認(rèn)證的使用,具有一定的參考價(jià)值,感興趣的可以了解一下2023-08-08
解決Django Static內(nèi)容不能加載顯示的問(wèn)題
今天小編就為大家分享一篇解決Django Static內(nèi)容不能加載顯示的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-07-07
Python練習(xí)之操作MySQL數(shù)據(jù)庫(kù)
這篇文章主要介紹了Python練習(xí)之操作MySQL數(shù)據(jù)庫(kù),文章通過(guò)如何創(chuàng)建MySQL數(shù)據(jù)表?如何向MySQL表中插入數(shù)據(jù)?如何查詢MySQL中的數(shù)據(jù)?的三個(gè)問(wèn)題展開(kāi)了詳細(xì)的內(nèi)容介紹2022-06-06
Python+Turtle實(shí)現(xiàn)繪制可愛(ài)的小倉(cāng)鼠
肉嘟嘟的小動(dòng)物很是可愛(ài),這篇文章主要為大家介紹一下如何運(yùn)用Python中的turtle庫(kù)控制函數(shù)繪制小倉(cāng)鼠,文中的實(shí)現(xiàn)方法講解詳細(xì),感興趣的可以嘗試一下2022-10-10
在python tkinter界面中添加按鈕的實(shí)例
今天小編就為大家分享一篇在python tkinter界面中添加按鈕的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-03-03
python PyQt5中QRadioButton的詳細(xì)使用教程與應(yīng)用實(shí)戰(zhàn)
PyQt5是一個(gè)跨平臺(tái)的GUI工具包,用于創(chuàng)建具有Python綁定的Qt應(yīng)用程序,在PyQt5中,QRadioButton是一個(gè)非常有用的控件,用于在用戶界面上提供單選選項(xiàng),本文將詳細(xì)介紹QRadioButton的基本用法、常用屬性和方法,需要的朋友可以參考下2024-08-08
輕松掌握python的dataclass讓你的代碼更簡(jiǎn)潔優(yōu)雅
本文總結(jié)了幾個(gè)我在使用Python的dataclass時(shí)常用的技巧,dataclass裝飾器可以幫助我們簡(jiǎn)化數(shù)據(jù)類的定義過(guò)程,包括設(shè)置默認(rèn)值、隱藏敏感信息、設(shè)置只讀對(duì)象以及將其轉(zhuǎn)化為元組和字典,通過(guò)使用dataclass,我們可以更高效地進(jìn)行數(shù)據(jù)分析和處理,感興趣的朋友跟隨小編一起看看吧2025-01-01

