Board logo

标题: [讨论]汉诺塔 [打印本页]

作者: s11ss     时间: 2007-9-21 13:01    标题: [讨论]汉诺塔

我不知道我的代码到底有没有问题.但是输入非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 ]
作者: slore     时间: 2007-9-21 15:29
把echo off去掉……

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

可能算法没有错误,但是limit,某些命令有限制……不能超过太多吧……
作者: dosmania     时间: 2007-9-21 16:02
这游戏用批处理搞不定吧``若可以的话,那么排数字游戏也能用批处理写了
````
作者: s11ss     时间: 2007-9-21 18:51


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

我不是要编游戏,只是给出解决方案
作者: HAT     时间: 2007-9-21 20:54
call命令递归的调用的太多了吧
关注
作者: s11ss     时间: 2007-9-22 12:52
今天终于搞定了:)





@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
作者: s11ss     时间: 2007-9-22 12:57
把:MoveOneDiscs全替换成:MoveManyDiscs