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连接DB2数据库
Aug 27 Python
python学习基础之循环import及import过程
Apr 22 Python
python 实现求解字符串集的最长公共前缀方法
Jul 20 Python
对python自动生成接口测试的示例讲解
Nov 30 Python
用Q-learning算法实现自动走迷宫机器人的方法示例
Jun 03 Python
Python基础之字符串常见操作经典实例详解
Feb 26 Python
python变量的作用域是什么
May 26 Python
python 中的9个实用技巧,助你提高开发效率
Aug 30 Python
详解查看Python解释器路径的两种方式
Oct 15 Python
Python批量修改xml的坐标值全部转为整数的实例代码
Nov 26 Python
Python基础之操作MySQL数据库
May 06 Python
python3读取文件指定行的三种方法
May 24 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
PHP的异常处理类Exception的使用及说明
2012/06/13 PHP
php自定义中文字符串截取函数substr_for_gb2312及substr_for_utf8示例
2016/05/28 PHP
Python中使用django form表单验证的方法
2017/01/16 PHP
JQuery 插件制作实践 xMarquee插件V1.0
2010/04/02 Javascript
jQuery 在光标定位的地方插入文字的插件
2012/05/10 Javascript
Firefox和IE兼容性问题及解决方法总结
2013/10/08 Javascript
jquery动态改变form属性提交表单
2014/06/03 Javascript
javascript实现修改微信分享的标题内容等
2014/12/11 Javascript
JavaScript实现节点的删除与序号重建实例
2015/08/05 Javascript
Bootstrap BootstrapDialog使用详解
2017/02/17 Javascript
vue.js 获取select中的value实例
2018/03/01 Javascript
30分钟快速入门掌握ES6/ES2015的核心内容(下)
2018/04/18 Javascript
关于js对textarea换行符的处理方法浅析
2018/08/03 Javascript
Element UI框架中巧用树选择器的实现
2018/12/12 Javascript
vue实现固定位置显示功能
2019/05/30 Javascript
localstorage实现带过期时间的缓存功能
2019/06/28 Javascript
vue自定义标签和单页面多路由的实现代码
2020/05/03 Javascript
Vue解决echart在element的tab切换时显示不正确问题
2020/08/03 Javascript
vue 全局封装loading加载教程(全局监听)
2020/11/05 Javascript
浅谈Ant Design Pro 菜单自定义 icon
2020/11/17 Javascript
element-ui中el-upload多文件一次性上传的实现
2020/12/02 Javascript
[03:36]DOTA2完美大师赛coL战队趣味视频——我演你猜
2017/11/23 DOTA
[01:14]TI珍贵瞬间系列(六):冠军
2020/08/30 DOTA
[47:42]完美世界DOTA2联赛PWL S2 GXR vs Ink 第一场 11.19
2020/11/20 DOTA
Python去掉字符串中空格的方法
2014/03/11 Python
python实现从字符串中找出字符1的位置以及个数的方法
2014/08/25 Python
使用PDB模式调试Python程序介绍
2015/04/05 Python
python解决js文件utf-8编码乱码问题(推荐)
2018/05/02 Python
python中数组和矩阵乘法及使用总结(推荐)
2019/05/18 Python
Django自定义全局403、404、500错误页面的示例代码
2020/03/08 Python
python em算法的实现
2020/10/03 Python
在线购买廉价折扣书籍和小说:BookOutlet.com
2018/02/19 全球购物
美国羽绒床上用品第一品牌:Pacific Coast
2018/08/25 全球购物
体育教师工作总结的自我评价
2013/10/10 职场文书
小学运动会广播稿200字(十二篇)
2014/01/14 职场文书
整脏治乱工作简报
2015/07/21 职场文书