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文件的md5加密方法
Apr 06 Python
10 行 Python 代码教你自动发送短信(不想回复工作邮件妙招)
Oct 11 Python
python 读取Linux服务器上的文件方法
Dec 27 Python
详解python selenium 爬取网易云音乐歌单名
Mar 28 Python
Python爬虫实现爬取百度百科词条功能实例
Apr 05 Python
Python实现Mysql数据统计及numpy统计函数
Jul 15 Python
Python字符串的修改方法实例
Dec 19 Python
判断Threading.start新线程是否执行完毕的实例
May 02 Python
JAVA及PYTHON质数计算代码对比解析
Jun 10 Python
Python获取浏览器窗口句柄过程解析
Jul 25 Python
详解如何使用Pytest进行自动化测试
Jan 14 Python
Pytorch中使用ImageFolder读取数据集时忽略特定文件
Mar 23 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
给多个地址发邮件的类
2006/10/09 PHP
PHP读取txt文件的内容并赋值给数组的代码
2011/11/03 PHP
php中拷贝构造函数、赋值运算符重载
2012/07/25 PHP
PHP中的str_repeat函数在JavaScript中的实现
2013/09/16 PHP
ThinkPHP添加更新标签的方法
2014/12/05 PHP
PHP递归遍历指定目录的文件并统计文件数量的方法
2015/03/24 PHP
asp.net+js 实现无刷新上传解析csv文件的代码
2010/05/17 Javascript
js中split和replace的用法实例
2015/02/28 Javascript
Javascript动态创建表格及删除行列的方法
2015/05/15 Javascript
jQuery满屏焦点图左右滚动特效代码分享
2015/09/07 Javascript
学习JavaScript正则表达式
2015/11/13 Javascript
使用Bootstrap框架制作查询页面的界面实例代码
2016/05/27 Javascript
第八篇Bootstrap下拉菜单实例代码
2016/06/21 Javascript
jquery+css3实现熊猫tv导航代码分享
2018/02/12 jQuery
小程序实现列表点赞功能
2018/11/02 Javascript
基于vue手写tree插件的那点事儿
2019/08/20 Javascript
layui 实现加载动画以及非真实加载进度的方法
2019/09/23 Javascript
bootstrap-table后端分页功能完整实例
2020/06/01 Javascript
微信小程序之导航滑块视图容器功能的实现代码(简单两步)
2020/06/19 Javascript
python使用xlrd实现检索excel中某列含有指定字符串记录的方法
2015/05/09 Python
linux下python抓屏实现方法
2015/05/22 Python
python使用fcntl模块实现程序加锁功能示例
2017/06/23 Python
python实现给微信指定好友定时发送消息
2019/04/29 Python
django 框架实现的用户注册、登录、退出功能示例
2019/11/28 Python
Python 基于FIR实现Hilbert滤波器求信号包络详解
2020/02/26 Python
Python面向对象程序设计之私有变量,私有方法原理与用法分析
2020/03/23 Python
兰蔻美国官网:Lancome美国
2017/04/25 全球购物
什么是规则表达式
2012/05/03 面试题
设置器与访问器的定义以及各自特点
2016/01/08 面试题
村党支部公开承诺书
2014/05/29 职场文书
开业庆典活动策划方案
2014/09/21 职场文书
教师党员自我评价范文
2015/03/04 职场文书
表彰大会新闻稿
2015/07/17 职场文书
2019安全宣传标语大全
2019/08/14 职场文书
golang中的并发和并行
2021/05/08 Golang
python脚本框架webpy模板赋值实现
2021/11/20 Python