中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
作者:
标题: [讨论]汉诺塔 上一主题 | 下一主题
s11ss
银牌会员





积分 2098
发帖 566
注册 2007-9-11
状态 离线
『楼 主』:  [讨论]汉诺塔

我不知道我的代码到底有没有问题.但是输入非1的数时,运行结果是:

******  B A T C H   R E C U R S I O N  exceeds STACK limits ******
Recursion Count=866, Stack Usage=90 percent
******       B A T C H   PROCESSING IS   A B O R T E D      ******




源代码如下:
@echo off
setlocal enabledelayedexpansion
::::::::::::::::::::::::::::      汉诺塔      ::::::::::::::::::::::::::::
::::::::::::::::::::::::::::{s11ss  2007-9-21}::::::::::::::::::::::::::::
:r
echo 问题:
echo 1.有三根杆子A,B,C。A杆上有若干碟子,根据直径从小到大编号;
echo 2.每次移动一块碟子,小的只能叠在大的上面;  
echo 3.把所有碟子从A杆全部移到C杆上。
echo.
echo 请输入最初A杆上的碟子数:
set /p n=
echo.
echo 解决方案:
set /a counter=1
set /a nn=!n!
set /a nnn=!n!
call :m !n! A B C
goto :eof
:m
set A=%1
set B=%2
set C=%3
if !n! equ 1 (
        call :p 1 %A% %C%
        goto :eof
) else (
        set /a nn=!nn!-1& call :m !nn! %A% %C% %B%
        call :p !n! %A% %C%
        set /a nnn=!nnn!-1& call :m !nn! %B% %A% %C%
        goto :eof
)
:p
echo !counter!. 把碟子%1号从%2杆移到%3杆
set /a counter+=1
goto :eof
:e
echo.
echo Press Any Key To Exit...
pause>nul
原代码已修改如下:但只是碟子数是1或2的时候有正确解:
@echo off
setlocal enabledelayedexpansion
::::::::::::::::::::::::::::      汉诺塔      ::::::::::::::::::::::::::::
::::::::::::::::::::::::::::{s11ss  2007-9-21}::::::::::::::::::::::::::::
:r
echo 问题:
echo 1.有三根杆子A,B,C。A杆上有若干碟子,根据直径从小到大编号;
echo 2.每次移动一块碟子,小的只能叠在大的上面;  
echo 3.把所有碟子从A杆全部移到C杆上。
echo.
echo 请输入最初A杆上的碟子数:
set /p n=
echo.
echo 解决方案:
set /a counter=1
::set /a nn=%n%        ::goto :eof)
::set /a nnn=%n%
call :m %n% A B C
goto :eof
:m
set /a nn=%1
set A=%2
set B=%3
set C=%4
if %nn% equ 1 (
        call :p 1 %A% %C%
) else (
        set /a nnn=%nn%-1
        call :m !nnn! %A% %C% %B%
        call :p %nn% %A% %C%
        call :m !nnn! %B% %A% %C%
)
goto :eof
:p
echo %counter%. 把碟子%1号从%2杆移到%3杆
set /a counter+=1
goto :eof
:e
echo.
echo Press Any Key To Exit...
pause>nul
今天终于搞定了!
@echo off
::::::::::::::::::::::::::::      汉诺塔      ::::::::::::::::::::::::::::
::::::::::::::::::::::::::::{s11ss  2007-9-22}::::::::::::::::::::::::::::
echo 问题:
echo 1.有三根杆子A,B,C。A杆上有若干碟子,根据直径从小到大编号;
echo 2.每次移动一块碟子,小的只能叠在大的上面;  
echo 3.把所有碟子从A杆全部移到C杆上。
echo.
:RecNum
echo 请输入最初A杆上的碟子数:
set /p n=
if "%n%" equ "" goto :RecNum
set /a seq=0
:CheckNum
if %n% gtr 31 (echo 溢出...最大只能是31。 & goto :RecNum)
call set one=%%n:~%seq%,1%%
if not "%one%" equ "" (
        set isnum=False
        for /l %%a in (0,1,9) do (
                if "%one%" equ "%%a" (
                        set /a seq+=1
                        set isnum=True
                        goto :CheckNum
                )
        )
)
if %isnum% equ False goto :RecNum
set /a r=1
for /l %%a in (1,1,%n%) do (
        set /a r*=2
)
set /a stepno=%r%-1
set flag=
set /p c=是否只计算要经历多少步?(y/n)
if %c% equ y goto :CalCounter
if %c% equ Y goto :CalCounter
set /p w=是否将解决方案写入到文件%n%_HanoTower.txt?(y/n):
if not %w% equ y (if not %w% equ Y (goto :Main))
:WriteFile
set flag=^>^>%n%_HanoTower.txt
echo off >%n%_HanoTower.txt
:Main
echo.
echo 计算中...
echo.
%flag% echo 最初A杆上的碟子数是%n%。
%flag% echo 解决方案:
set /a counter=0
set punctuation=;
call :MoveOneDiscs %n% A B C
goto :EchoExit
:MoveOneDiscs
set /a nn=%1
set A=%2
set B=%3
set C=%4
if %nn% equ 1 (
        call :MoveOneDisc 1 %A% %C%
) else (
        call :MoveOneDiscs %nn%-1 %A% %C% %B%
        call :MoveOneDisc %nn% %A% %C%
        call :MoveOneDiscs %nn%-1 %B% %A% %C%
)
goto :eof
:MoveOneDisc
set /a counter+=1
if %counter% equ %stepno% (set punctuation=。)
%flag% echo %counter%. 把碟子%1号从%2杆移到%3杆%punctuation%
goto :eof
:CalCounter
set /a counter=%stepno%
:EchoExit
echo.
echo 最少须%counter%步。
echo 方案已解决。
echo 按任意键退出...
pause>nul
[ Last edited by s11ss on 2007-9-22 at 12:49 PM ]

2007-9-21 13:01
查看资料  发短消息 网志   编辑帖子  回复  引用回复
slore
铂金会员





积分 5212
发帖 2478
注册 2007-2-8
状态 离线
『第 2 楼』:  

把echo off去掉……

B A T C H   R E C U R S I O N  exceeds STACK limits

可能算法没有错误,但是limit,某些命令有限制……不能超过太多吧……

2007-9-21 15:29
查看资料  发短消息 网志   编辑帖子  回复  引用回复
dosmania
初级用户





积分 172
发帖 54
注册 2007-1-2
状态 离线
『第 3 楼』:  

这游戏用批处理搞不定吧``若可以的话,那么排数字游戏也能用批处理写了
````

2007-9-21 16:02
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
s11ss
银牌会员





积分 2098
发帖 566
注册 2007-9-11
状态 离线
『第 4 楼』:  



  Quote:
Originally posted by dosmania at 2007-9-21 04:02 PM:
这游戏用批处理搞不定吧``若可以的话,那么排数字游戏也能用批处理写了
````

我不是要编游戏,只是给出解决方案

2007-9-21 18:51
查看资料  发短消息 网志   编辑帖子  回复  引用回复
HAT
版主





积分 9023
发帖 5017
注册 2007-5-31
状态 离线
『第 5 楼』:  

call命令递归的调用的太多了吧
关注

2007-9-21 20:54
查看资料  发短消息 网志   编辑帖子  回复  引用回复
s11ss
银牌会员





积分 2098
发帖 566
注册 2007-9-11
状态 离线
『第 6 楼』:  

今天终于搞定了:)





@echo off
::::::::::::::::::::::::::::      汉诺塔      ::::::::::::::::::::::::::::
::::::::::::::::::::::::::::{s11ss  2007-9-22}::::::::::::::::::::::::::::
echo 问题:
echo 1.有三根杆子A,B,C。A杆上有若干碟子,根据直径从小到大编号;
echo 2.每次移动一块碟子,小的只能叠在大的上面;  
echo 3.把所有碟子从A杆全部移到C杆上。
echo.
:RecNum
echo 请输入最初A杆上的碟子数:
set /p n=
if "%n%" equ "" goto :RecNum
set /a seq=0
:CheckNum
if %n% gtr 31 (echo 溢出...最大只能是31。 & goto :RecNum)
call set one=%%n:~%seq%,1%%
if not "%one%" equ "" (
        set isnum=False
        for /l %%a in (0,1,9) do (
                if "%one%" equ "%%a" (
                        set /a seq+=1
                        set isnum=True
                        goto :CheckNum
                )
        )
)
if %isnum% equ False goto :RecNum
set /a r=1
for /l %%a in (1,1,%n%) do (
        set /a r*=2
)
set /a stepno=%r%-1
set flag=
set /p c=是否只计算要经历多少步?(y/n)
if %c% equ y goto :CalCounter
if %c% equ Y goto :CalCounter
set /p w=是否将解决方案写入到文件%n%_HanoTower.txt?(y/n):
if not %w% equ y (if not %w% equ Y (goto :Main))
:WriteFile
set flag=^>^>%n%_HanoTower.txt
echo off >%n%_HanoTower.txt
:Main
echo.
echo 计算中...
echo.
%flag% echo 最初A杆上的碟子数是%n%。
%flag% echo 解决方案:
set /a counter=0
set punctuation=;
call :MoveOneDiscs %n% A B C
goto :EchoExit
:MoveOneDiscs
set /a nn=%1
set A=%2
set B=%3
set C=%4
if %nn% equ 1 (
        call :MoveOneDisc 1 %A% %C%
) else (
        call :MoveOneDiscs %nn%-1 %A% %C% %B%
        call :MoveOneDisc %nn% %A% %C%
        call :MoveOneDiscs %nn%-1 %B% %A% %C%
)
goto :eof
:MoveOneDisc
set /a counter+=1
if %counter% equ %stepno% (set punctuation=。)
%flag% echo %counter%. 把碟子%1号从%2杆移到%3杆%punctuation%
goto :eof
:CalCounter
set /a counter=%stepno%
:EchoExit
echo.
echo 最少须%counter%步。
echo 方案已解决。
echo 按任意键退出...
pause>nul

2007-9-22 12:52
查看资料  发短消息 网志   编辑帖子  回复  引用回复
s11ss
银牌会员





积分 2098
发帖 566
注册 2007-9-11
状态 离线
『第 7 楼』:  

把:MoveOneDiscs全替换成:MoveManyDiscs

2007-9-22 12:57
查看资料  发短消息 网志   编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: