使用python从三个角度解决josephus问题的方法


Posted in Python onMarch 27, 2020

0 写在前面

josephus问题是数据结构教材中的一个常见实例,其问题可以描述为:

设nnn个人围坐一圈,现在要求从第kkk个人开始报数,报到第mmm个的人退出。然后从下一个人开始继续按照同样规则报数并退出,直到所有人退出为止。要求按照顺序输出每个人的序列号。

1 基于数组概念的解法

首先考虑基于python的list和固定大小的数组概念,即将list看作元素个数固定的对象,只改变值而不删除元素,相当于摆了一圈nnn把椅子,人虽然退出但是椅子还在,我们可以给每个人从111到nnn编号,没有人的位置用000表示,思路如下:

初始

  • 建立包含nnn个人(编号)的list
  • 找到第kkk个人开始

运行

  • 从kkk的位置开始数到mmm,中间遇到000的就跳过
  • 数到mmm之后,将其值改为000
  • 然后继续循环,总共循环nnn次(因为每次循环就会退出一个人)

代码如下:

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,真正记的数是i
    if num < n-1:
      print(end=",", )
    else:
      print(" ")

2 基于顺序表的解法

顺序表是线性表的一种,即表中元素放在一块足够大的连续存储区里,首元素存入存储区开始位置,其余元素依次存放。顺序表在python中的也是list,跟第一种解法不同,当第mmm个人退出需要进行删除元素的操作,才是顺序表。而第一种解法的数组想要删除并不是那么容易,这里是因为python中没有内置对数组的支持,所以用list代替,具体可以参照c++中的数组,如果要删除中间的某个元素的话,必须对后面的元素重新编号。代码实现如下:

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 基于循环单链表的解法

单链表即单向链接表,典型的就是c++中的链表,循环单链表就是头尾相连的单链表,也是线性表的一种,这道题目使用循环单链表记录nnn个人围坐一圈最为契合。我们只需要数到第mmm个结点就删除,删除操作对于链表来说比较容易,而且不需要有i = (i+1) % n这样的整除操作。但是问题在于python并没有像c++那样有内置对链表的支持,因此需要建立一个链表的类,建立是比较麻烦的,但是操作比较简单,如下:

class LNode: # 建立链表结点
  def __init__(self,elem,next_=None):
    self.elem=elem
    self.next=next_
class LCList: # 建立循环链接表
  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 # 建立一个结点的环
      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

到此这篇关于使用python从三个角度解决josephus问题的方法的文章就介绍到这了,更多相关python josephus问题内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python爬取网站数据保存使用的方法
Nov 20 Python
Python使用scrapy抓取网站sitemap信息的方法
Apr 08 Python
详解Python当中的字符串和编码
Apr 25 Python
EM算法的python实现的方法步骤
Jan 02 Python
Python基于Floyd算法求解最短路径距离问题实例详解
May 16 Python
对matplotlib改变colorbar位置和方向的方法详解
Dec 13 Python
python linecache 处理固定格式文本数据的方法
Jan 08 Python
Python中常用的8种字符串操作方法
May 06 Python
Python实现的ftp服务器功能详解【附源码下载】
Jun 26 Python
python 中Arduino串口传输数据到电脑并保存至excel表格
Oct 14 Python
MxNet预训练模型到Pytorch模型的转换方式
May 25 Python
python的html标准库
Apr 29 Python
解决django接口无法通过ip进行访问的问题
Mar 27 #Python
Django 实现将图片转为Base64,然后使用json传输
Mar 27 #Python
python实现简单坦克大战
Mar 27 #Python
Django实现从数据库中获取到的数据转换为dict
Mar 27 #Python
Python生成器实现简单&quot;生产者消费者&quot;模型代码实例
Mar 27 #Python
python数据库编程 Mysql实现通讯录
Mar 27 #Python
python数据库编程 ODBC方式实现通讯录
Mar 27 #Python
You might like
PHP 根据IP地址控制访问的代码
2010/04/22 PHP
几款免费开源的不用数据库的php的cms
2010/12/19 PHP
php中使用PHPExcel读写excel(xls)文件的方法
2014/09/15 PHP
Whatever:hover 无需javascript让IE支持丰富伪类
2010/06/29 Javascript
基于jquery的bankInput银行卡账号格式化
2012/08/22 Javascript
html a标签-超链接中confirm方法使用介绍
2013/01/04 Javascript
jQuery插件开发的五种形态小结
2015/03/04 Javascript
在JavaScript中操作时间之getMonth()方法的使用
2015/06/10 Javascript
jquery控制显示服务器生成的图片流
2015/08/04 Javascript
AngularJS中的Directive自定义一个表格
2016/01/25 Javascript
原生JS实现层叠轮播图
2017/05/17 Javascript
React Native中Navigator的使用方法示例
2017/10/13 Javascript
解决vue2中使用axios http请求出现的问题
2018/03/05 Javascript
vue init webpack myproject构建项目 ip不能访问的解决方法
2018/03/20 Javascript
100行代码实现一个vue分页组功能
2018/11/06 Javascript
微信接入之获取用户头像的方法步骤
2019/09/23 Javascript
在VUE style中使用data中的变量的方法
2020/06/19 Javascript
python爬虫入门教程之糗百图片爬虫代码分享
2014/09/02 Python
使用Python的Tornado框架实现一个一对一聊天的程序
2015/04/25 Python
Python爬虫实现爬取京东手机页面的图片(实例代码)
2017/11/30 Python
python微信跳一跳系列之棋子定位颜色识别
2018/02/26 Python
Django使用详解:ORM 的反向查找(related_name)
2018/05/30 Python
Python数据可视化:箱线图多种库画法
2019/11/06 Python
让Django的BooleanField支持字符串形式的输入方式
2020/05/20 Python
利用python下载scihub成文献为PDF操作
2020/07/09 Python
python批量合成bilibili的m4s缓存文件为MP4格式 ver2.5
2020/12/01 Python
HTML5 CSS3新的WEB标准和浏览器支持
2009/07/16 HTML / CSS
Trip.com香港网站:Ctrip携程旗下,全球最大的网上旅游社之一
2016/08/01 全球购物
高一自我鉴定
2013/12/17 职场文书
授权委托书样本
2014/04/03 职场文书
乡镇干部个人对照检查材料思想汇报
2014/10/04 职场文书
父亲婚礼答谢词
2015/01/04 职场文书
员工自我工作评价
2015/03/06 职场文书
MongoDB数据库的安装步骤
2021/06/18 MongoDB
python中取整数的几种方法
2021/11/07 Python
Django中celery的使用项目实例
2022/07/07 Python