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的Flask框架的简介和安装方法
Nov 13 Python
python计算两个地址之间的距离方法
Jun 09 Python
Python开发的十个小贴士和技巧及长常犯错误
Sep 27 Python
Python发展简史 Python来历
May 14 Python
python async with和async for的使用
Jun 20 Python
Django中使用session保持用户登陆连接的例子
Aug 06 Python
jupyter notebook 调用环境中的Keras或者pytorch教程
Apr 14 Python
Python常用断言函数实例汇总
Nov 30 Python
pandas将list数据拆分成行或列的实现
Dec 13 Python
python实现图片转字符画的完整代码
Feb 21 Python
浅谈Python xlwings 读取Excel文件的正确姿势
Feb 26 Python
详细介绍python操作RabbitMq
Apr 12 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
WML,Apache,和 PHP 的介绍
2006/10/09 PHP
在页面上点击任一链接时触发一个事件的代码
2007/04/07 Javascript
JavaScript高级程序设计 阅读笔记(十二) js内置对象Math
2012/08/14 Javascript
JScript分割字符串示例代码
2013/09/04 Javascript
js在数组中删除重复的元素自保留一个(两种实现思路)
2014/08/22 Javascript
基于javascript、ajax、memcache和PHP实现的简易在线聊天室
2015/02/03 Javascript
详解JavaScript对Date对象的操作问题(生成一个倒数7天的数组)
2015/10/01 Javascript
jquery 抽奖小程序实现代码
2016/10/12 Javascript
Node.js下自定义错误类型详解
2016/10/17 Javascript
jQuery Validate插件自定义验证规则的方法
2016/12/27 Javascript
微信小程序商城项目之淘宝分类入口(2)
2017/04/17 Javascript
微信小程序request出现400的问题解决办法
2017/05/23 Javascript
nodejs实现解析xml字符串为对象的方法示例
2018/03/14 NodeJs
vue弹窗插件实战代码
2018/09/08 Javascript
vue中keep-alive组件的入门使用教程
2019/06/06 Javascript
vue+layui实现select动态加载后台数据的例子
2019/09/20 Javascript
vue 导航锚点_点击平滑滚动,导航栏对应变化详解
2020/08/10 Javascript
Python中处理unchecked未捕获异常实例
2015/01/17 Python
Python开发SQLite3数据库相关操作详解【连接,查询,插入,更新,删除,关闭等】
2017/07/27 Python
Flask框架信号用法实例分析
2018/07/24 Python
python+PyQT实现系统桌面时钟
2020/06/16 Python
浅谈PYTHON 关于文件的操作
2019/03/19 Python
Python爬虫——爬取豆瓣电影Top250代码实例
2019/04/17 Python
解决python明明pip安装成功却找不到包的问题
2019/08/28 Python
pytorch中的weight-initilzation用法
2020/06/24 Python
css3中less实现文字长阴影(long shadow)
2020/04/24 HTML / CSS
Java程序开发中如何应用线程
2016/03/03 面试题
学习十八大坚定理想信念心得体会
2014/03/11 职场文书
新学期决心书
2014/03/11 职场文书
感恩老师的演讲稿
2014/05/06 职场文书
计算机软件专业求职信
2014/06/10 职场文书
2015年医务科工作总结范文
2015/05/26 职场文书
红色革命电影观后感
2015/06/18 职场文书
党风廉洁教育心得体会
2016/01/20 职场文书
详解python的内存分配机制
2021/05/10 Python
MySQL限制查询和数据排序介绍
2022/03/25 MySQL