一、软件背景介绍

我们今天要陈述的应用叫做汉诺塔,大家可能小时候都接触过类似于鲁班锁,九连环的益智玩具,我们要说的汉诺塔其实也可以说是益智玩具的一种。 下面我们具体介绍一下汉诺塔。汉诺塔有三根杆子A,B,C。A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。求按下列规则将所有圆盘移至C杆,必须遵循以下原则:

每次只能移动一个圆盘

大盘不能叠在小盘上面

所以在这个前提下,我们做的程序就可以更快更精确的完成这个汉诺塔盘子从A盘移动到C盘的详细过程,具体算法和程序以及代码我们在后面的文档中会涉及到。下面给出汉诺塔程序设计的一种简单情况,以三个盘子的汉诺塔移动过程为例。

以三个盘子为例,过程如下图所示:

本程序在dosbox中运行需用户输入汉诺塔的盘子数,目前仅支持输入1至9,具体运行效果如图1图示过程,用户输入窗口如下图:

程序在运行过程中的按下Esc键,程序会弹出提示是否退出汉诺塔演示,输入Y则退出,输入N则退出,效果如下图:

二、核心算法思想

如下图所示,从左到右有A、B、C三根柱子,其中A柱子上面有从小叠到大的n个圆盘,现要求将A柱子上的圆盘移到C柱子上去,期间只有两个原则:一次只能移到一个盘子且大盘子不能在小盘子上面,求移动的步骤和移动的次数。

解:这里我们先用一些数学方法求解

(1)n==1

第1次1号盘A---->C sum=1次

(2)n==2

第1次1号盘A---->B

第2次2号盘A---->C

第3次1号盘B---->C sum=3次

(3)n==3

第1次1号盘A---->C

第2次2号盘A---->B

第3次1号盘C---->B

第4次3号盘A---->C

第5次1号盘B---->A

第6次2号盘B---->C

第7次1号盘A---->C sum=7次

不难发现规律:1个圆盘的次数2的1次方减1

2个圆盘的次数2的2次方减1

3个圆盘的次数2的3次方减1

……

n个圆盘的次数2的n次方减1

所以我们可以发现移动次数为:2^n – 1

我们在利用计算机求汉诺塔问题时,必不可少的一步是对整个实现求解进行算法分析。到目前为止,求解汉诺塔问题最简单的算法还是同过递归来求, 再加上上面数学问题解法的分析,我们不难发现,移到的步数必定为奇数步:

中间的一步是把最大的一个盘子由A移到C上去

中间一步之上可以看成把A上n-1个盘子借助辅助塔C塔移到了B上

中间一步之下可以看成把B上n-1个盘子借助辅助塔A塔移到了C上

首先把三根柱子按顺序排成品字型,把所有的圆盘按从大到小的顺序放在柱子A上,根据圆盘的数量确定柱子的排放顺序:

若n为偶数,按顺时针方向依次摆放 A B C;若n为奇数,按顺时针方向依次摆放 A C B

按顺时针方向把圆盘1从现在的柱子移动到下一根柱子,即当n为偶数时,若圆盘1在柱子A,则把它移动到B;若圆盘1在柱子B,则把它移动到C;若圆盘1在柱子C,则把它移动到A

接着,把另外两根柱子上可以移动的圆盘移动到新的柱子上。即把非空柱子上的圆盘移动到空柱子上,当两根柱子都非空时,移动较小的圆盘

反复进行(1)(2)操作,最后就能按规定完成汉诺塔的移动。

如3阶汉诺塔的移动:

A→C,A→B,C→B,A→C,B→A,B→C,A→C

三、核心算法流程图

汉诺塔动画演示的算法流程图如下:

图3为汉诺塔图形演示的简单流程图,用以明确程序圆形过程中的各个部分模块,清楚程序运行的步骤,是汉诺塔演示中的宏观过程的流程。

图4为汉诺塔程序的算法流程图,描述了程序在运行过程中的详细步骤,涵盖了程序的应输入的条件,汉诺塔中的盘子应该何时移动,往哪里移动,应移动几个盘子等诸多问题在程序中的实现。

四、开发中遇到的问题

第一点是我想整体上先去陈述,顺便提一个最后的小细节。我们制定项目后,在自以为编写完成后,却发现自己弄好的代码运行不了,需要不断地去调试,检查在哪里出现错误,再加以修改,这本就是一个艰辛的过程。尤其最后我们的代码提示只有一个错误缺少“start”时,我们怎么加也没有用,都要崩溃了。不过感谢上课时刘老师的提醒,我们把结尾的“start”删去,才终于运行好了程序。

第二点是在开发过程中怎样去完成汉诺塔的过程,汉诺塔的盘子是如何在三根轴线上正确移动的。通过在纸上自己进行的汉诺塔游戏发现五个盘子以上还是比较有难度的,在网上搜查资料后发现了一种比较容易解决的方法。这种方法是一个只要轮流进行两步操作就可以了。首先把三根柱子按顺序排成品字型,把所有的圆盘按从大到小的顺序放在柱子A上,根据圆盘的数量确定柱子的排放顺序:若n为偶数,按顺时针方向依次摆放 A B C;若n为奇数,按顺时针方向依次摆放 A C B。

按顺时针方向把圆盘1从现在的柱子移动到下一根柱子,即当n为偶数时,若圆盘1在柱子A,则把它移动到B;若圆盘1在柱子B,则把它移动到C;若圆盘1在柱子C,则把它移动到A

接着,把另外两根柱子上可以移动的圆盘移动到新的柱子上。即把非空柱子上的圆盘移动到空柱子上,当两根柱子都非空时,移动较小的圆盘。这一步没有明确规定移动哪个圆盘,你可能以为会有多种可能性,其实不然,可实施的行动是唯一的

反复进行⑴⑵操作,这样最终就能按规定完成汉诺塔的移动

通过查阅资料和自己的验证发现实现这个算法可以简单分为三个步骤:

把n-1个盘子由A 移到 B

把第n个盘子由 A移到 C

把n-1个盘子由B 移到 C

从这里入手,在加上上面数学问题解法的分析,我们不难发现,移到的步数必定为奇数步:

中间的一步是把最大的一个盘子由A移到C上去

中间一步之上可以看成把A上n-1个盘子借助辅助塔C塔移到B上

中间一步之下可以看成把B上n-1个盘子借助辅助塔A塔移到C上

第三点是开发过程中如何用图形化的方式将汉诺塔过程显示出来。关于这一点,我们想了很久也没有思路。后来我们意识到自己的能力肯定有不足,于是我们决定向老师请教,于是我们去了学院楼老师办公室,向老师咨询了这个问题,后来老师告诉我们,可以通过定义宏的方式在窗口上画出汉诺塔的基本要素和操作,定义了竖线的宏,横线的宏和矩形的宏,用以描绘汉诺塔的形状和盘子,定义了up,down,left,right等子程序通过递减盘子的横纵坐标来实现盘子的上下左右的基本移动,通过bottom参数来实现盘子位置的确定,并通过递归的主函数实现汉诺塔盘子从A借助辅助轴移到C的过程。

以上三点大抵上是我们开发中遇到的“三座大山”,庆幸来自各方的努力,我们终于克服。不过记录下来总是好的。

六、心得体会

大一期间学习了一些高级语言,如C语言,c++,在对一些实际问题的编程处理上使用这些高级语言显得很是方便。于是在刚接触汇编语言这门课的时候,就对其实用性产生了怀疑和一些的抵触情绪。一开始,虽然对一些繁杂的指令有些厌恶,但为了项目还是硬着头皮学着下来了,再经过后来的学习感觉汇编语言并不是那么的枯燥无味,而是很有实际用途的。在很多问题的处理上,汇编语言编程很是节省系统的资源。汇编的学习不仅仅是学习其语法,而更多的是学习计算机基本的体系结构,汇编语言有很多的指令和语句,这是学习汇编前必须要知道和掌握的,只有知道了汇编的实质、如何工作及一些基本概念,才能进行下一步的学习。直到后面学到了80×86指令系统和寻址方式及后来的汇编语言格式,才真正进入了汇编的指令学习阶段,每一条指令的学习虽然简单但比较多,特别是有些指令的使用场合及错误用法等易犯错、易混淆。例如在编写数据传送指令时,目的操作数和源操作数的类型一定要匹配,CS不能作为目的操作数等。但总的归纳起来主要掌握三点:

要求指令操作数的寻址方式

指令对标志位的影响和标志位对指令的影响

指令的执行时间,对可完成同样功能的指令,要选用执行时间短的指令

这样学习起来方便的多,也更容易理解记住,这为以后的学习做了铺垫。

身为一名转专业生,对于同学大一的知识暂时缺乏了解,加上对汇编语言的畏难情绪,一开始的我是很没有自信的,所以一拿到要求就显得无从下手,不知道怎么去操作。一开始也做了很多草稿,总是无疾而终,后来在另一个队友的陪伴下,定下来汉诺塔这个主题,于是我们开始了艰辛地一段路途,也在各方面的努力下最终完成了这个课题,心里十分激动。对于汇编语言,我了解到汇编语言不像其他大多数的程序设计语言一样被广泛用于程序设计。在今天的实际应用中,它通常被应用在底层,硬件操作和高要求的程序优化的场合。

C语言编程求解圆盘的汉诺塔,课内资源 - 基于80x86汇编的汉诺塔相关推荐

  1. python编程输出汉字_课内资源 - 基于Python的拼音汉字转换程序

    1.实验内容利用统计语言模型实现拼音汉字转换 输入:拼音串,输出:对应的汉字串 给定10000字的测试语料,测试音字转换的准确率 针对音字转换结果中存在的问题给出具体分析 以图表的形式表示上述结果 2 ...

  2. 餐厅管理程序c语言源代码,课内资源 - 基于C++的餐厅管理程序的设计与实现

    摘 要 随着计算机应用技术的快速发展和日益普及,网络也遍及到我们生活的每个角落,为我们的学习和工作带来极大的方便.很多人都使用过传统的文字,纸张管理手段,与之不同的另外一种管理方式就是利用电脑程序管理 ...

  3. c语言文字冒险类游戏,课内资源 - 基于C语言和easyx实现的巧虎划船大冒险游戏...

    1 需求分析 1.1 功能需求 游戏性:通过键盘方向键的←.→.↑.↓来控制巧虎(船)的移动,躲避暗礁,碰撞宝物(特殊宝物),来增加积分,在倒计时结束前(到达终点前)争取得到更多分数.为提高可玩性,宝 ...

  4. java实现一元多项式减法,课内资源 - 基于C语言实现的一元多项式的计算

    一.概述 通过C语言使用链式存储结构实现一元多项式加法.减法和乘法的运算.按指数降序排列. 二.需求分析 建立一元多项式并按照指数降序排列输出多项式,将一元多项式输入并存储在内存中,能够完成两个多项式 ...

  5. c语言全民飞机游戏代码,课内资源 - 基于VC++和OpenCV实现的全民飞机大战游戏

    摘要功能:利用C++语言完成了一个小游戏项目-全民飞机大战,该游戏首先能够给用户提供注册,登录功能:提供了菜单栏及两种游戏模式,一种是无尽模式,另一种是一般模式:一般模式中用户通过控制玩家飞机攻击敌方 ...

  6. 数学金字塔C语言原函数,课内资源 - 基于C语言实现的金字塔问题(Pyramid Problem)...

    1 开发软件说明 Dev C++是一个 Windows 下的C 和C++程序的集成开发环境,是一款自由软件,遵守GPL 许可协议分发源代码.它使用MingW32/GCC 编译器,遵循 C/C++ 11 ...

  7. c语言外卖程序,课内资源 - 基于C语言的外卖派单模拟系统

    一.课题任务概述 你运行一家外卖快递服务店,负责一个区域内的外卖订单接收和餐食快递.你有一笔启动资金,可以招募外卖骑手帮你送餐,来赚取快递费.但你也会面临风险,本区域的订单你都有义务接收,不能拒绝,若 ...

  8. 用c语言写扫雷游戏倒计时代码,课内资源 - 基于VS2013实现的扫雷小游戏

    1.任务概述 1.1 系统总体目标 本项目的目的在于开发一个扫雷软件,该软件面向游戏玩家用户,具有进行扫雷游戏的功能.游戏玩家将使用系统中的如下功能: 进行游戏 使用自定义游戏规格功能 使用计时器功能 ...

  9. C语言家谱管理程序,课内资源 - 基于C语言实现的家谱管理系统

    一.项目简介 家谱是一种以表谱形式,记载一个以血缘关系为主体的家族世袭繁衍和重要任务事迹的特殊图书体裁.家谱是中国特有的文化遗产,是中华民族的三大文献(国史,地志,族谱)之一,属于珍贵的人文资料,对于 ...

最新文章

  1. c51语言的标准库函的头文件,C51编程中头文件的使用
  2. c++虚函数_「C++」对象模型和虚函数
  3. deepin--解决屏幕撕裂问题
  4. llmp_install.zip
  5. rhel7+apache+c cgi+动态域名实现web访问
  6. 织梦php网站修改教程,织梦DEDEcms织梦软件模型增加图集功能教程(含修改文件下载)...
  7. WPF——创建可观察的枚举器
  8. lightoj 1016
  9. html考勤表格模板,Excel员工考勤表模板如何撤销工作表保护?
  10. 整理几个高质量Java自学网站
  11. 文章翻译软件-批量免费翻译软件支持各大翻译接口
  12. 内网渗透工具-反向代理nps使用分析
  13. 自动化测试框架基石工程
  14. css仿支付宝提现到账过程时间轴
  15. 如何在word中设置带悬挂缩进对齐的多行???
  16. 玩转冷板式液冷 你需要一份靠谱的“设计参考”
  17. “第二届openGauss每日一练打卡活动” 获奖名单公布!
  18. python汉语词典_Python 字典(Dictionary)
  19. 【漏洞复现】MS17-010漏洞(永恒之蓝)复现
  20. 不同进制之间的转换的各种方法

热门文章

  1. java取余位运算_使用位运算取余
  2. 大数据学习的有哪些相关书籍
  3. esp8266启动报错 ets Jan 8 2013,rst cause:2, boot mode:(7,7)
  4. 《构建之法》第一次作业——阅读与准备工作
  5. “ Linux基础知识学习 ” 之 关于rc.d文件的理解 04
  6. 【题目】NKOJ-4247 老蒋的数列
  7. gwu计算机硕士排名,美国乔治华盛顿大学计算机专业排名 研究方向有哪些
  8. EMC基础知识总结,写的太全了!
  9. 送给linux***爱好者的小技巧 分享
  10. 09 数据存储Introduce