python实现汉诺塔算法


Posted in Python onMarch 01, 2021

题目:

汉诺塔给出最优解,如果对汉诺塔的定义有不了解,请翻看数据结构教材。

除了最基本的之外,还有一题,给定一个数组,arr=[2,3,1,2,3],其含义是这是一个有5个圆盘的汉诺塔,每一个数字代表这个圆盘所在的位置,1代表左边的柱子,2代表中间,3代表右边。给出这个序列代表了汉诺塔移动的第几步,如果该步骤是错误的,则返回-1,所谓错误,是指该步骤不是最简便的得到汉诺塔序列的操作步骤。

分析:

1、 算法当然还是递归解了,即把n个汉诺塔盘子分解成 n - 1 个盘子的移动和一个底层盘子的移动,这样一来,问题就成了一连串的递归,然后就可以逐步求解了。
当然了,汉诺塔还有进阶问题,此处先不讨论,随后补上吧。

2、 这个步骤的循环是从最右边开始的,考察最大的圆盘,因为数组的索引值越大,其圆盘的半径越大。
这样一来,如果最大的圆盘的值为3,说明已经移动到位了,如果为1,说明还没有开始移动底层圆盘,如果为2,说明圆盘移动到了中间,表示移动错误,因为根本不需要移动到中间,这个步骤是多余的。

代码:

#!usr/bin/python2.7
# -*- coding=utf8 -*-
# @Time : 18-1-3 下午9:52
# @Author : Cecil Charlie


class Hanoi(object):
 """
 汉诺塔问题,给定三个盘子,用计算机计算出来将所有的盘子从左移动到右的所有的操作。
 """
 def __init__(self):
 self.place = ["left", "middle", "right"]
 self.num = 0 # 表示所有操作的总次数

 def hanoi(self, n):
 """
  给定一个n,即汉诺塔的盘子数量,返回所有的从左移动到右侧的具体操作步数
 :param n: 盘子数
 :return: 具体操作
 """
 self.num = 0
 if n > 0:
  self.__move(n, "left", "middle", "right")

 def __move(self, n, start, mid, end):
 if n == 1:
  print "move from " + start + " to " + end
  self.num += 1
 else:
  self.__move(n-1, start, end, mid)
  self.__move(1, start, mid, end)
  self.__move(n-1, mid, start, end)

 def step(self, arr):
 """
  求解针对arr的圆盘,所对应的最优解到底是第几步。解题的核心在于从右向左考察圆盘到底在不在3位置,如果在,则说明已经移动成功了;
  如果在中间,说明移动出现了错误,因为不需要移动到中间,如果还在左边,则仍需要考虑。
 :param arr: 列表中每一项表示该项的圆盘在哪个柱子上,取值包括1,2,3。1表示左,2表示中,3表示右,索引值越大,表示的圆盘的半径越大。
 :return: 属于最优解的第几步
 """
 if arr is None:
  return -1
 for i in xrange(len(arr) - 1):
  if arr[i] != 1 and arr[i] != 2 and arr[i] != 3:
  return -1
 return self.__process(arr, len(arr)-1, 1, 2, 3)

 def __process(self, arr, i, start, mid, end):
 """
  具体操作得到arr属于第几步
 :param arr: 圆盘对应的位置数组列表
 :param i: 考察arr圆盘的第几个,最大值是 len(arr)-1
 :return: 返回步数,如果给出的arr的位置不是移动的最优解,则返回 -1。
 """
 if i == -1:
  return 0
 if arr[i] != start and arr[i] != end:
  return -1
 if arr[i] == start:
  return self.__process(arr, i-1, start, end, mid) # 说明其值还未过半,直接找之前的就好
 else: # 说明步数已经过半了。
  count = self.__process(arr, i-1, mid, start, end)
  if count == -1:
  return -1
  return (i * 2) + count

h = Hanoi()
h.hanoi(4)
print h.num
print h.step([3,3,2,1])

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python多线程扫描端口示例
Jan 16 Python
Python深入学习之对象的属性
Aug 31 Python
初步探究Python程序的执行原理
Apr 11 Python
Python加载带有注释的Json文件实例
May 23 Python
Sanic框架Cookies操作示例
Jul 17 Python
python调用百度语音识别实现大音频文件语音识别功能
Aug 30 Python
python可视化爬虫界面之天气查询
Jul 03 Python
python+numpy按行求一个二维数组的最大值方法
Jul 09 Python
python使用requests.session模拟登录
Aug 09 Python
Python如何调用JS文件中的函数
Aug 16 Python
python基于TCP实现的文件下载器功能案例
Dec 10 Python
Python  lambda匿名函数和三元运算符
Apr 19 Python
Python3中bytes类型转换为str类型
Sep 27 #Python
python求解数组中两个字符串的最小距离
Sep 27 #Python
Python开发的十个小贴士和技巧及长常犯错误
Sep 27 #Python
详解django中使用定时任务的方法
Sep 27 #Python
Python高级特性切片(Slice)操作详解
Sep 27 #Python
Python初学者需要注意的事项小结(python2与python3)
Sep 26 #Python
使用 Python 实现微信群友统计器的思路详解
Sep 26 #Python
You might like
Laravel 实现Eloquent模型分组查询并返回每个分组的数量 groupBy()
2019/10/23 PHP
详解PHP中的8个魔术常量
2020/07/06 PHP
HTML中不支持静态Expando的元素的问题
2007/03/08 Javascript
无语,javascript居然支持中文(unicode)编程!
2007/04/12 Javascript
List Installed Hot Fixes
2007/06/12 Javascript
jquery单行文字向上滚动效果示例
2014/03/06 Javascript
node.js中的buffer.write方法使用说明
2014/12/10 Javascript
jQuery中:reset选择器用法实例
2015/01/04 Javascript
javascript实现获取图片大小及图片等比缩放的方法
2016/11/24 Javascript
ES6新特性之字符串的扩展实例分析
2017/04/01 Javascript
Javascript es7中比较实用的两个方法示例
2017/07/21 Javascript
jQuery Dom元素操作技巧
2018/02/04 jQuery
vue父子组件通信的高级用法示例
2019/08/29 Javascript
Element-ui el-tree新增和删除节点后如何刷新tree的实例
2020/08/31 Javascript
在Python中编写数据库模块的教程
2015/04/29 Python
python里dict变成list实例方法
2019/06/26 Python
简单了解django orm中介模型
2019/07/30 Python
你可能不知道的Python 技巧小结
2020/01/29 Python
Jupyter Notebook 实现正常显示中文和负号
2020/04/24 Python
使用Python FastAPI构建Web服务的实现
2020/06/08 Python
Python接口测试环境搭建过程详解
2020/06/29 Python
Python RabbitMQ实现简单的进程间通信示例
2020/07/02 Python
python excel和yaml文件的读取封装
2021/01/12 Python
HTML5 video播放器全屏(fullScreen)方法实例
2015/04/24 HTML / CSS
Feelunique中文官网:欧洲最大化妆品零售电商
2020/07/10 全球购物
专业毕业生个性的自我评价
2013/10/03 职场文书
公务员职务工作的自我评价
2013/11/01 职场文书
安全生产检讨书
2014/01/21 职场文书
初中同学聚会邀请函
2014/02/03 职场文书
租房协议书
2014/04/10 职场文书
餐饮投资计划书
2014/04/25 职场文书
心理学专业求职信
2014/06/16 职场文书
《观潮》教学反思
2016/02/17 职场文书
修改MySQL的默认密码的四种小方法
2021/05/26 MySQL
java如何实现socket连接方法封装
2021/09/25 Java/Android
输入框跟随文字内容适配宽实现示例
2022/08/14 Javascript