Board logo

标题: 【练习-053】按要求补全变量嵌套中的批处理代码 [打印本页]

作者: batman    时间: 2009-11-20 16:37     标题: 【练习-053】按要求补全变量嵌套中的批处理代码

出题目的:
    1、初步了解变量嵌套概念
    2、搞清楚cmd对变量的解析(值的释放)过程
加分原则:
    满分10分
题目如下:
    有一简单的变量嵌套代码如下:
  1. @echo off&setlocal enabledelayedexpansion
  2. set "a=bathome"
  3. ::以下for循环实现的是set "b=a"&set "c=b"&set "d=c"&set "e=d"
  4. for %%a in (ba cb dc ed) do set "str=%%a"&set "!str:~,1!=!str:~1!"
复制代码
请补全代码,要求只用e变量的解析式来输出结果“bathome”,也就是说你知道e变量
以及中间变量的转承过程,但在解析式中不能用到%a% %b% %c% %d%或!a! !b! !c! !d!,只
能用到%e%或!e!。
作者: 523066680    时间: 2009-11-20 17:08

这么快又发一道题…… 是基础题。
做法1:
set e=!%e%!
set e=!%e%!
set e=!%e%!
echo !%e%!
pause
作者: batman    时间: 2009-11-21 10:51     标题: 回复 2楼 的帖子

就本题而言你这样的做法是正确的,但假如中间有100道转承关系呢?

[ 本帖最后由 batman 于 2009-11-21 10:53 编辑 ]
作者: 523066680    时间: 2009-11-21 11:10

那就用一个循环来“递推”吧
仍然可能考虑goto 循环,

因为在for中是复合句,%var%总是for之前的结果 ,也许还会考虑进一步for替换!! 吧
这些都是方法
call %%!!%% 的方式,因为大家都说call低效,于是我也开始避开了

[ 本帖最后由 523066680 于 2009-11-21 11:14 编辑 ]
作者: batman    时间: 2009-11-21 11:38

&&本人认为采用for循环的方式来解析应该是一种替归的方式,

不然当存在大量中间变量和转承关系时,单用for也解决不了。

同时exist上面提到的循环递推的方式和本人提到的for循环替

归方式都是可以忽略中间有多少层变量和转承这个条件的,唯

一只是要设置中止条件而己(变量值为空)。

[ 本帖最后由 batman 于 2009-11-21 11:40 编辑 ]
作者: tevktev    时间: 2009-11-21 12:11

  1. :again
  2. set e=!%e%!
  3. if  "%e%"=="bathome" ( echo %e%&pause&goto :eof)else goto again
复制代码
不明白用FOR怎么去实现,只能用这种方法了。

[ 本帖最后由 tevktev 于 2009-11-21 20:24 编辑 ]
作者: batman    时间: 2009-11-21 17:18

大家都想一下怎么用for来实现这一变量解析的过程,

提示:用一个for表达式来代替n个for嵌套表达式,可

参考下面这个代码:
  1. @echo off
  2. set "str=a-b-c-d-e-f-g-h-i-j"
  3. call :lp "%str%"
  4. pause>nul&goto :eof
  5. :lp
  6. for /f "tokens=1* delims=-" %%a in (%1) do (
  7.       if "%%b" neq "" (
  8.          call :lp "%%b"
  9.          ) else (
  10.          echo %%a
  11.       )
  12. )
复制代码

[ 本帖最后由 batman 于 2009-11-21 17:27 编辑 ]
作者: temp    时间: 2009-11-21 17:33

做什么用呢?

俺不懂!
作者: batman    时间: 2009-11-21 17:39     标题: 回复 8楼 的帖子

顶楼有出题的目的说明,这是道基础知识类的题,不是要展示你的技巧,而是要考察你的基本概念和思路。
作者: Seter    时间: 2009-11-21 17:56

  1. @echo off&setlocal enabledelayedexpansion
  2. set "a=bathome"
  3. ::以下for循环实现的是set "b=a"&set "c=b"&set "d=c"&set "e=d"
  4. for %%a in (ba cb dc ed) do set "str=%%a"&set "!str:~,1!=!str:~1!"
  5. call :lp e
  6. pause&goto :eof
  7. :lp
  8. if defined %~1 (call %0 !%~1!)else echo %~1
复制代码

作者: vsbat    时间: 2009-11-21 19:13

  1. @echo off&setlocal enabledelayedexpansion
  2. set "a=bathome"
  3. ::以下for循环实现的是set "b=a"&set "c=b"&set "d=c"&set "e=d"
  4. for %%a in (ba cb dc ed) do set "str=%%a"&set "!str:~,1!=!str:~1!"
  5. call,call,call,set e=%%%%%%%%%%%%%%%e%%%%%%%%%%%%%%%
  6. call,echo %%%e%%%
  7. pause
复制代码



::虽然 call 效率低 但也想贴出来(针对本题的转承次数)
回去想了想---可以一call到底
call,call,call,call,echo %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%e%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[ 本帖最后由 vsbat 于 2009-11-22 13:14 编辑 ]
作者: tevktev    时间: 2009-11-21 20:20     标题: 回复 7楼 的帖子

中止有误?
能不能给出修正后的代码。
谢谢

[ 本帖最后由 tevktev 于 2009-11-21 20:27 编辑 ]
作者: batman    时间: 2009-11-21 20:43     标题: 回复 12楼 的帖子

if  "%e%"=="bathome" 应该是if "%e%"=="",你不能直接将最后的值写出来,换句话就是你根本不知道最后的值是多少。
作者: fish    时间: 2010-8-1 23:46     标题: 累死俺了,数了一晚上呢。。。

  1. @echo off&setlocal enabledelayedexpansion
  2. set "a=bathome"
  3. ::以下for循环实现的是set "b=a"&set "c=b"&set "d=c"&set "e=d"
  4. for %%a in (ba cb dc ed) do set "str=%%a"&set "!str:~,1!=!str:~1!"
  5. call call call call set /p=e=%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%e%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6. pause
复制代码
发现这样还简洁点,请问各位前辈,还能再简洁不了呢。。。
  1. @echo off&setlocal enabledelayedexpansion
  2. set "a=bathome"
  3. ::以下for循环实现的是set "b=a"&set "c=b"&set "d=c"&set "e=d"
  4. for %%a in (ba cb dc ed) do set "str=%%a"&set "!str:~,1!=!str:~1!"
  5. call call call set /p=e=%%%%%%%%%%%%%%!%e%!%%%%%%%%%%%%%%
  6. pause
复制代码

[ 本帖最后由 fish 于 2010-8-1 23:51 编辑 ]
作者: terse    时间: 2010-8-2 03:33

  1. @echo off&setlocal enabledelayedexpansion
  2. set "a=bathome"
  3. set "b=a"&set "c=b"&set "d=c"&set "e=d"
  4. for %%i in (b c d) do for %%j in ("!%%i!") do set %%i=!%%~j!
  5. echo !%e%!
  6. pause
复制代码

作者: fish    时间: 2010-8-2 15:31     标题: 回复 15楼 的帖子

请问terse前辈为什么不这样写呢?
  1. @echo off&setlocal enabledelayedexpansion
  2. set "a=bathome"
  3. set "b=a"&set "c=b"&set "d=c"&set "e=d"
  4. for %%i in (b c d) do for %%j in (!%%i!) do set %%i=!%%j!
  5. echo !%e%!
  6. pause
复制代码

作者: pgfj18    时间: 2010-8-2 19:36

  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set "a=bathome"
  4. ::以下for循环实现的是set "b=a"&set "c=b"&set "d=c"&set "e=d"
  5. for %%a in (ba cb dc ed) do set "str=%%a"&set "!str:~,1!=!str:~1!"
  6. for /l %%i in () do if defined  !e! (call set e=%%!e!%%) else echo !e!&pause&exit
复制代码

[ 本帖最后由 pgfj18 于 2010-8-2 22:57 编辑 ]




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2