使用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 获取文件列表(或是目录例表)
Mar 25 Python
python 图片验证码代码分享
Jul 04 Python
Python中apply函数的用法实例教程
Jul 31 Python
Python 序列的方法总结
Oct 18 Python
Python实现pdf文档转txt的方法示例
Jan 19 Python
python 匹配url中是否存在IP地址的方法
Jun 04 Python
python验证码识别教程之利用滴水算法分割图片
Jun 05 Python
Python除法之传统除法、Floor除法及真除法实例详解
May 23 Python
pytorch 批次遍历数据集打印数据的例子
Dec 30 Python
python画图常规设置方式
Mar 05 Python
Python 3.9的到来到底是意味着什么
Oct 14 Python
Flask使用SQLAlchemy实现持久化数据
Jul 16 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个人网站架设连环讲(一)
2006/10/09 PHP
php实现telnet功能示例
2014/04/08 PHP
CI框架中数据库操作函数$this-&gt;db-&gt;where()相关用法总结
2016/05/17 PHP
php从数据库中获取数据用ajax传送到前台的方法
2018/08/20 PHP
jquery 表单下所有元素的隐藏
2009/07/25 Javascript
jquery判断浏览器后退时候弹出消息的方法
2014/08/11 Javascript
JQuery表格拖动调整列宽效果(自己动手写的)
2014/09/01 Javascript
jquery中animate的stop()方法作用实例分析
2015/01/30 Javascript
JavaScript中实现map功能代码分享
2015/06/11 Javascript
JS模仿编辑器实时改变文本框宽度和高度大小的方法
2015/08/17 Javascript
jquery输入数字随机抽奖特效的简单实现代码
2016/06/10 Javascript
AngularJs Understanding the Controller Component
2016/09/02 Javascript
TableSort.js表格排序插件使用方法详解
2017/02/10 Javascript
详解有关easyUI的拖动操作中droppable,draggable用法例子
2017/06/03 Javascript
vue绑定class与行间样式style详解
2017/08/16 Javascript
JavaScript html5 canvas实现图片上画超链接
2017/10/20 Javascript
小程序ios音频播放没声音问题的解决
2018/07/11 Javascript
详解微信小程序-canvas绘制文字实现自动换行
2019/04/26 Javascript
jQuery实现动态向上滚动
2020/12/21 jQuery
详解python上传文件和字符到PHP服务器
2017/11/24 Python
python dataframe astype 字段类型转换方法
2018/04/11 Python
python实现根据文件关键字进行切分为多个文件的示例
2018/12/10 Python
Django之创建引擎索引报错及解决详解
2019/07/17 Python
Django模板Templates使用方法详解
2019/07/19 Python
挪威太阳镜和眼镜网上商城:SmartBuyGlasses挪威
2016/08/20 全球购物
adidas旗下高尔夫装备供应商:TaylorMade Golf(泰勒梅高尔夫)
2016/08/28 全球购物
婴儿鞋,独特的婴儿服装和配件:Zutano
2018/11/03 全球购物
String是最基本的数据类型吗?
2013/06/13 面试题
物业管理求职自荐信
2013/09/25 职场文书
技校生自我鉴定范文
2013/09/26 职场文书
最新的大学生找工作自我评价
2013/09/29 职场文书
优秀企业获奖感言
2014/02/01 职场文书
工程质量承诺书范文
2014/03/27 职场文书
2014年团员学习十八大思想汇报
2014/09/13 职场文书
小学2016年第十八届推普周活动总结
2016/04/05 职场文书
浅谈Redis 中的过期删除策略和内存淘汰机制
2022/04/03 Redis