hanoi 问题

问题描述

下面的程序通过修改WindowBox类的num和gap修改盘子个数和时间间隔可以正确运行,但是为什么在菜单的设置选项里,设置之后,画布就不再变化了,而是一直保持原来运行的结果呢?令外,运行完以后,最大化最小化,窗口,盘子的大小为什么会变化呢?急啊代码如下:importjavax.swing.*;importjava.awt.*;importjavax.swing.border.*;importjava.awt.event.*;publicclasshanoi{/***@paramargs*/publicstaticvoidmain(String[]args){//TODOAuto-generatedmethodstubWindowBoxwb=newWindowBox();}}//获取移动结果classHanoiResult{intarray[][];//移动步数intstate[][];//每次移动各个柱子的盘子intcount;//移动步数intnum;//盘子个数HanoiResult(){array=newint[200][3];state=newint[2000][3];}//获取移动的结果voidgetResult(){init_array();hanoi(num,1,2,3);/*for(inti=0;i<=count;i++){for(intj=0;j<3;j++)System.out.print(array[i][j]);System.out.println();}*//*for(inti=0;i<num*(count+1);i++){for(intj=0;j<3;j++)System.out.print(state[i][j]);System.out.println();if((i+1)%num==0)System.out.println("*******");}*//*for(inti=0;i<num;i++)System.out.println(state[i][0]+""+state[i][1]+""+state[i][2]);*/}//初始化数组voidinit_array(){array[0][0]=num;array[1][0]=num;for(inti=0;i<1000;i++)for(intj=0;j<3;j++)state[i][j]=0;for(inti=0;i<num;i++)state[i][0]=i+1;for(inti=num;i<2*num;i++)state[i][0]=i-num+1;}//获取n号柱子上的最大盘子intgetbiggest(intm,intn){inti,flag;for(i=0;i<num&&state[m+i][n]!=0;i++);flag=state[m+i-1][n];state[m+i-1][n]=0;returnflag;};//将j号盘子放到第n号柱子上voidins(intm,intn,intj){inti;for(i=0;i<num&&state[m+i][n]!=0;i++);state[m+i][n]=j;};voidmov(inta,intb){array[count+1][--a]--;array[count+1][--b]++;for(inti=0;i<3;i++)array[count+2][i]=array[count+1][i];ins((count+1)*num,b,getbiggest((count+1)*num,a));for(inti=0;i<num;i++)for(intj=0;j<3;j++)state[(count+2)*num+i][j]=state[(count+1)*num+i][j];count++;}voidhanoi(intn,inta,intb,intc){if(n==1)mov(a,c);else{hanoi(n-1,a,c,b);mov(a,c);hanoi(n-1,b,a,c);}}voidsetnum(intnum){this.num=num;}}//窗口类classWindowBoxextendsFrameimplementsActionListener{HanoiResulthr;//hanoi对象doublet;//计时intgap;//时间间隔Boxhb,vb;mycanvasca1,ca2,ca3;//画布对戏那个MenuBarmenubar;Menumenu1,menu2;MenuItemitem1,item3,item4;Labelbottom;NumDialogdialog1;intnum;WindowBox(){num=3;gap=500;t=0;ca1=newmycanvas();ca2=newmycanvas();ca3=newmycanvas();ca1.setBackground(Color.orange);ca2.setBackground(Color.cyan);ca3.setBackground(Color.green);dialog1=newNumDialog(this,"设定运行参数",true);menubar=newMenuBar();menu1=newMenu("文件");menu2=newMenu("选项");item1=newMenuItem("设定参数…");item3=newMenuItem("退出");item4=newMenuItem("关于");menu1.add(item1);menu1.add(item3);menu2.add(item4);menubar.add(menu1);menubar.add(menu2);setMenuBar(menubar);setTitle("汉诺塔问题演示");setBackground(Color.pink);hr=newHanoiResult();bottom=newLabel("已运行时间0已移动步数0(时间间隔尚未设定)");hb=Box.createHorizontalBox();vb=Box.createVerticalBox();hb.add(Box.createHorizontalStrut(8));hb.add(ca1);hb.add(Box.createHorizontalStrut(4));hb.add(ca2);hb.add(Box.createHorizontalStrut(4));hb.add(ca3);hb.add(Box.createHorizontalStrut(8));vb.add(hb);vb.add(bottom);setLayout(newFlowLayout());add(vb);addWindowListener(newWindowAdapter(){publicvoidwindowClosing(WindowEvente){System.exit(0);}});setBounds(200,20,624,620);setVisible(true);item1.addActionListener(this);item3.addActionListener(this);item4.addActionListener(this);run();}//运行函数publicvoidrun(){hr.setnum(num);ca1.setnum(num);ca2.setnum(num);ca3.setnum(num);hr.getResult();try{item1.setEnabled(false);}catch(Exceptione){};for(inti=0;i<=hr.count;i++){redraw(ca1,ca2,ca3,hr.array[i][0],hr.array[i][1],hr.array[i][2],i);}item1.setEnabled(true);}//菜单监听@OverridepublicvoidactionPerformed(ActionEvente){//TODOAuto-generatedmethodstubif(e.getSource()==item1){dialog1.setVisible(true);hr=newHanoiResult();t=0;this.num=dialog1.getnum();this.gap=(int)(dialog1.gettime()*1000);//System.out.println("num"+num);//System.out.println("time"+gap);run();}elseif(e.getSource()==item3)System.exit(0);elseif(e.getSource()==item4){hr=newHanoiResult();t=0;this.num=4;this.gap=500;run();}}//重画函数publicvoidredraw(mycanvasca1,mycanvasca2,mycanvasca3,inta,intb,intc,intcs){inti;bottom.setText("已运行时间"+t+"秒已移动步数"+(cs)+"(时间间隔为0.5s)");for(i=0;i<num;i++){ca1.state[i]=hr.state[cs*num+i][0];}//重画画布1ca1.draw(a);for(i=0;i<num;i++){ca2.state[i]=hr.state[cs*num+i][1];}//重画画布2ca2.draw(b);for(i=0;i<num;i++){ca3.state[i]=hr.state[cs*num+i][2];}//重画画布3ca3.draw(c);t=t+gap/1000.0;//延时gaptry{Thread.sleep(gap);}catch(InterruptedExceptione){}}}classmycanvasextendsCanvas{intnum,x,y,width;intstate[];voidsetnum(intnum){this.num=num;}voiddraw(intnum){this.num=num;this.repaint();}mycanvas(){state=newint[10];setBounds(10,10,200,550);}//每多一个x+8,y-60,width-16;底层(30,490,140,50,20,20)publicvoidpaint(Graphicsg){for(inti=0;i<num;i++)state[i]--;inty=490;for(inti=0;i<num;i++){g.drawRoundRect(30+8*state[i],y,140-16*state[i],50,20,20);y-=60;}}}//对话框类classNumDialogextendsDialogimplementsActionListener{Stringnum_str;Stringtime_str;intnum;doubletime;Buttonconfirm,cancel;TextFieldnum_input;TextFieldtime_input;Labeltip1,tip2,num_label,time_label;Boxhr1,hr2,hr3,hv;NumDialog(Framef,Strings,booleanb){super(f,s,b);hr1=Box.createHorizontalBox();hr2=Box.createHorizontalBox();hr3=Box.createHorizontalBox();tip1=newLabel("必须输入1-8的整数");tip2=newLabel("为获得最好视觉效果时间最好不要超过1s");num_label=newLabel("盘子个数");time_label=newLabel("时间间隔");hv=Box.createVerticalBox();num_input=newTextField();time_input=newTextField();confirm=newButton("运行");cancel=newButton("取消");confirm.addActionListener(this);cancel.addActionListener(this);setLayout(newFlowLayout());hr1.add(num_label);hr1.add(Box.createHorizontalStrut(5));hr1.add(num_input);hr2.add(time_label);hr2.add(Box.createHorizontalStrut(5));hr2.add(time_input);hr3.add(confirm);hr3.add(Box.createHorizontalStrut(10));hr3.add(cancel);hv.add(tip1);hv.add(tip2);hv.add(Box.createVerticalStrut(20));hv.add(hr1);hv.add(Box.createVerticalStrut(10));hv.add(hr2);hv.add(Box.createVerticalStrut(15));hv.add(hr3);add(hv);setBounds(400,100,400,300);addWindowListener(newWindowAdapter(){publicvoidwindowClosing(WindowEvente){setVisible(false);}});}publicintgetnum(){returnnum;}publicdoublegettime(){returntime;}@OverridepublicvoidactionPerformed(ActionEvente){//TODOAuto-generatedmethodstubif(e.getSource()==confirm){num_str=num_input.getText();time_str=time_input.getText();try{num=Integer.valueOf(num_str);time=Float.valueOf(time_str);}catch(NumberFormatExceptionexce){tip1.setText("输入有误:必须输入1-8的整数!");}setVisible(false);}elseif(e.getSource()==cancel){setVisible(false);}}}

解决方案

解决方案二:
学会用调试来解决问题吧,学会自己分析和把问题表达清楚吧,总贴一大段代码上来,头都痛了。
解决方案三:
不是啊,我分析了好久,没弄出个所以然来,所以只有求助大虾了,另外这个程序只有这一个类,只要建一个hanoi类就可运行了,hanoi.java的代码就在上面,希望大家帮帮我……

时间: 2024-09-22 03:42:19

hanoi 问题的相关文章

用VB编写Hanoi塔问题动态演示程序

1 引言 在计算机算法设计中,使用递归技术往往使函数的定义和算法的描述简捷且易于理解.有些数据结构如二叉树等由于其本身固有的递归特性,特别适合用递归的形式来描述.还有一些问题,虽然其本身并没有明显的递归结构,但用递归技术来求解使设计出的算法简洁.易懂.因此深入掌握递归技术在算法设计过程中可以设计出更加有效的算法[1]. 简单地说,递归就是用自己定义自己.使用递归方法构造算法的基本思路是:当求解规模为n的问题时,先将其分解成若干个规模较小的与原问题具有相同特征的子问题,并找出子问题与原问题之间的组

【具体数学--读书笔记】1.1 The Power of Hanoi

这一节借助汉诺塔问题引入了"Reccurent Problems". (Reccurence, 在这里解释为"the solution to each problem depends on the solutions to smaller instances of the same problem". 即由相同的规模更小的问题的到原问题的解) Hanoi问题描述: "given a tower of eight disks, initially stack

java 汉诺塔Hanoi递归、非递归(仿系统递归)和非递归规律 实现代码_java

程序如下: 复制代码 代码如下: View Code  /*  * Hanoi塔游戏 问题描述:  * 汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.  * 大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照  * 大小顺序摞着64片黄金圆盘.大梵天命令婆罗门把圆盘从下面开始按大小  * 顺序重新摆放在另一根柱子上.并且规定,在小圆盘上不能放大圆盘,在  * 三根柱子之间一次只能移动一个圆盘.  *   * fuction:实现 hanoi塔  *       

Hanoi塔问题

Hanoi塔问题--递归方法求解     假设有三个分别命名为x.y.z的圆柱形塔座,在塔座x上插有n个半径大小各不相同,以小到大由上而下编号为1,2,····,n,如图所示.现在要求将X轴上的n个圆盘移至塔Z上并仍按原来的顺序叠放,圆盘移动时必须遵循以下规则: 1.每次只能移动一个圆盘 2.圆盘可以插在X.Y.Z任意一个塔座上 3.任何时刻都不能将一个较大的圆盘压在较小圆盘之上 如何实现圆盘的移动呢?这就要用到我们强大的递归思想.设一个变量n用来调用任意一个圆盘,当n=1时,只要将一号圆盘从X

汉诺塔迭代算法(Towers of Hanoi, classic problem (recursiv

//Towers of Hanoi, classic problem (recursive method)//Java how to program, 5/e, Exercise 6.37-38import javax.swing.*;import java.awt.*;import java.awt.event.*;public class HanoiTowers extends JApplet implements ActionListener { int number, starting,

[导入]Hanoi塔问题(C)

Hanoi塔问题文章来源:http://blog.csdn.net/chsword/archive/2007/03/02/1519003.aspx

POJ题目分类

初期: 一.基本算法:      (1)枚举. (poj1753,poj2965)      (2)贪心(poj1328,poj2109,poj2586)      (3)递归和分治法.      (4)递推.      (5)构造法.(poj3295)      (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996) 二.图算法:      (1)图的深度优先遍历和广度优先遍历.      (2)最短路径算法(dijkstra,bellman-ford

C语言学习教程第五章-函数(6)

函数的递归调用 一个函数在它的函数体内调用它自身称为递归调用. 这种函数称为递归函数.C语言允许函数的递归调用.在递归调用中, 主调函数又是被调函数.执行递归函数将反复调用其自身. 每调用一次就进入新的一层.例如有函数f如下:int f (int x){int y;z=f(y);return z;}这个函数是一个递归函数. 但是运行该函数将无休止地调用其自身,这当然是不正确的.为了防止递归调用无终止地进行, 必须在函数内有终止递归调用的手段.常用的办法是加条件判断, 满足某种条件后就不再作递归调

UVa 10795 A Different Task:汉诺塔&amp;amp;想法题

10795 - A Different Task Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=456&page=show_problem&problem=1736 The (Three peg) Tower of Hanoi problem is a popular one in computer science