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装饰器使用的一些建议
Jun 03 Python
利用python爬取散文网的文章实例教程
Jun 18 Python
python中numpy包使用教程之数组和相关操作详解
Jul 30 Python
使用python将多个excel文件合并到同一个文件的方法
Jul 09 Python
python numpy数组中的复制知识解析
Feb 03 Python
Python GUI编程学习笔记之tkinter中messagebox、filedialog控件用法详解
Mar 30 Python
python判断是空的实例分享
Jul 06 Python
Python发送邮件实现基础解析
Aug 14 Python
python根据字典的键来删除元素的方法
Aug 16 Python
python+openCV对视频进行截取的实现
Nov 27 Python
Python Selenium库的基本使用教程
Jan 04 Python
python常见的占位符总结及用法
Jul 02 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计算整个目录大小的方法
2015/06/01 PHP
PHP模板解析类实例
2015/07/09 PHP
PHP常用的三种设计模式汇总
2016/08/28 PHP
PHP实现的简单对称加密与解密方法实例小结
2017/08/28 PHP
ExtJS Ext.MessageBox.alert()弹出对话框详解
2010/04/02 Javascript
JS实现下拉框的动态添加(附效果)
2013/04/03 Javascript
实现动画效果核心方式的js代码
2013/09/27 Javascript
Jquery如何实现点击时高亮显示代码
2014/01/22 Javascript
巧用replace将文字表情替换为图片
2014/04/17 Javascript
jQuery中unbind()方法用法实例
2015/01/19 Javascript
JS动态修改表格cellPadding和cellSpacing的方法
2015/03/31 Javascript
JavaScript中setUTCFullYear()方法的使用简介
2015/06/12 Javascript
Vue实现动态响应数据变化
2017/04/28 Javascript
简单谈谈原生js的math对象
2017/06/27 Javascript
最后说说Vue2 SSR 的 Cookies 问题
2018/05/25 Javascript
vue+springmvc导出excel数据的实现代码
2018/06/27 Javascript
Vue中Axios从远程/后台读取数据
2019/01/21 Javascript
nodejs搭建本地服务器并访问文件操作示例
2019/05/11 NodeJs
Vue 实现点击空白处隐藏某节点的三种方式(指令、普通、遮罩)
2019/10/23 Javascript
vue + node如何通过一个Txt文件批量生成MP3并压缩成Zip
2020/06/02 Javascript
Django与遗留的数据库整合的方法指南
2015/07/24 Python
Python3实现带附件的定时发送邮件功能
2020/12/22 Python
Pycharm在创建py文件时,自动添加文件头注释的实例
2018/05/07 Python
Python实现两个list求交集,并集,差集的方法示例
2018/08/02 Python
使用 Python 处理 JSON 格式的数据
2019/07/22 Python
浅谈Python_Openpyxl使用(最全总结)
2019/09/05 Python
python 实现一个反向单位矩阵示例
2019/11/29 Python
使用scrapy ImagesPipeline爬取图片资源的示例代码
2020/09/28 Python
python re.match()用法相关示例
2021/01/27 Python
美国流行背包品牌:JanSport(杰斯伯)
2018/03/02 全球购物
警察先进个人事迹材料
2014/05/16 职场文书
励志演讲稿3分钟
2014/08/21 职场文书
乡镇党委书记第三阶段个人整改措施
2014/09/16 职场文书
教师个人发展总结
2015/02/11 职场文书
迎新生欢迎词2015
2015/07/16 职场文书
5种 JavaScript 方式实现数组扁平化
2021/10/05 Javascript