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中self原理实例分析
Apr 30 Python
python中map()与zip()操作方法
Feb 27 Python
CentOS 7下安装Python 3.5并与Python2.7兼容并存详解
Jul 07 Python
Python常见字典内建函数用法示例
May 14 Python
Python学习笔记基本数据结构之序列类型list tuple range用法分析
Jun 08 Python
python openvc 裁剪、剪切图片 提取图片的行和列
Sep 19 Python
Python高级编程之继承问题详解(super与mro)
Nov 19 Python
python GUI库图形界面开发之PyQt5计数器控件QSpinBox详细使用方法与实例
Feb 28 Python
opencv 图像腐蚀和图像膨胀的实现
Jul 07 Python
python 实现百度网盘非会员上传超过500个文件的方法
Jan 07 Python
python实现发送邮件
Mar 02 Python
python实现剪贴板的操作
Jul 01 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
珊瑚虫IP库浅析
2007/02/15 PHP
批量获取memcache值并按key的顺序返回的实现代码
2011/06/14 PHP
PHP图片处理类 phpThumb参数用法介绍
2012/03/11 PHP
php删除字符串末尾子字符,删除开始字符,删除两端字符(实现代码)
2013/06/27 PHP
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 2611816 bytes)
2014/11/08 PHP
PHP合并数组的2种方法小结
2016/11/24 PHP
如何在标题栏显示框架内页面的标题
2007/02/03 Javascript
Exitjs获取DataView中图片文件名
2009/11/26 Javascript
用Javascript评估用户输入密码的强度实现代码
2011/11/30 Javascript
jQuery实现列表自动滚动循环滚动展示新闻
2014/08/22 Javascript
jQuery的animate函数实现图文切换动画效果
2015/05/03 Javascript
js命名空间写法示例
2015/12/18 Javascript
JS产生随机数的几个用法详解
2016/06/22 Javascript
JavaScript生成验证码并实现验证功能
2016/09/24 Javascript
js设置和获取自定义属性的方法
2016/10/20 Javascript
关于Iframe父页面与子页面之间的相互调用
2016/11/22 Javascript
微信小程序商城项目之侧栏分类效果(1)
2017/04/17 Javascript
一步快速解决微信小程序中textarea层级太高遮挡其他组件
2019/03/04 Javascript
react写一个select组件的实现代码
2019/04/03 Javascript
layer.js open 隐藏滚动条的例子
2019/09/05 Javascript
[01:05:00]2018国际邀请赛 表演赛 Pain vs OpenAI
2018/08/24 DOTA
python实现上传样本到virustotal并查询扫描信息的方法
2014/10/05 Python
详解python如何调用C/C++底层库与互相传值
2016/08/10 Python
python 第三方库的安装及pip的使用详解
2017/05/11 Python
python如何读写csv数据
2018/03/21 Python
python实现超级马里奥
2020/03/18 Python
将tf.batch_matmul替换成tf.matmul的实现
2020/06/18 Python
Python调用飞书发送消息的示例
2020/11/10 Python
节约用水的口号
2014/06/20 职场文书
党的群众路线教育实践活动自我剖析材料
2014/10/08 职场文书
优秀班集体申报材料
2014/12/25 职场文书
2015年六一儿童节活动总结
2015/02/11 职场文书
上课迟到检讨书范文
2015/05/06 职场文书
公司岗位说明书
2015/10/08 职场文书
大学军训心得体会800字
2016/01/11 职场文书
spring cloud eureka 服务启动失败的原因分析及解决方法
2022/03/17 Java/Android