本帖最后由 zm900612 于 2011-4-24 11:29 编辑
若给定文本中不存在重字,这样比原始的40次变量替换更快,而且random的范围更加合理:- @echo off&setlocal enabledelayedexpansion&echo %time%
- for /f "useback skip=11" %%a in ("%~0") do set "str=!str!%%a"
- set str=@!str!
- for /l %%a in (0,1,16) do (
- set /a a=!random!%%12+1
- for %%b in (!a!) do call :str !str:~%%b,5!
- )
- for /l %%a in (1 8 33) do echo !str:~%%a,8!
- echo %time%&pause>nul
- :str
- for /f "tokens=1* delims=%1" %%a in ("!str!") do set "str=%%a!str:*%1=!%1"&exit /b
- 我们去北京踢球吧
- 快上那儿等着信号
- 你不能离开大门口
- 生与死就在一瞬间
- 青春已从身边溜走
复制代码 修改了“北大”为“北京”,16次call*5个字符的偏移范围,至少能把这40个字符循环两遍,保证随机性,同时random的取值范围降低,保证各部分字符串被随机选中的概率分布更为合理。
总之在效率和合理性上做了比较大的改进,相比原算法,最大的缺点就在于不支持重复字
现在发现,这似乎就是caruko说的“洗牌”算法,而且terse兄指出我绕弯了,其实只需要优化batman的代码就可以了...纯随机输出无重字文本时,这个大概是极限了(简化后的batman变量替换算法):- @echo off&setlocal enabledelayedexpansion&echo %time%
- for /f "skip=9 useback" %%a in ("%~0") do set "str=!str!%%a"
- for /l %%a in (0,1,40) do (
- for %%b in (!random:~-1!) do (
- for /f %%c in ("!str:~%%b,1!") do set str=!str:%%c=!%%c
- )
- )
- for /l %%a in (0 8 32) do echo !str:~%%a,8!
- echo %time%&pause>nul
- 我们去北京踢球吧
- 快上那儿等着信号
- 你不能离开大门口
- 生与死就在一瞬间
- 青春已从身边溜走
复制代码 另有简化后的变量偏移的算法,效率和变量替换相差无几,支持重复字,但是代码多了两行:- ;@echo off&setlocal enabledelayedexpansion&echo %time%
- ;for /f "useback" %%a in ("%~0") do set str=!str!%%a
- ;for /l %%a in (40 -1 1) do (
- ; set /a "ra=!random!%%%%a",n=ra+1
- ; for /f "tokens=1* delims=@" %%b in ("!ra!@!n!") do (
- ; set echo=!echo!!str:~%%b,1!
- ; set "str=!str:~0,%%b!!str:~%%c!"
- ; )
- ;)
- ;for /l %%a in (0 8 32) do echo !echo:~%%a,8!
- ;echo %time%&pause>nul&exit
- 我们去北大踢球吧
- 快上那儿等着信号
- 你不能离开大门口
- 生与死就在一瞬间
- 青春已从身边溜走走
复制代码 caruko提出的洗牌法,优点是可以轻易控制复杂程度和用时,缺点是经常洗不干净:- ;@echo off&setlocal enabledelayedexpansion&echo %time%
- ;for /f "useback" %%a in ("%~0") do set str=!str!%%a
- ;for /l %%a in (1 1 40) do (
- ; set /a ra=!random:~-1!+5
- ; for %%b in ("!ra!") do (
- ; set str=!str:~-%%~b!!str:~5,-%%~b!!str:~0,5!
- ; )
- ;)
- ;for /l %%a in (0 8 32) do echo !str:~%%a,8!
- ;echo %time%&pause>nul&exit
- 我们去北大踢球吧
- 快上那儿等着信号
- 你不能离开大门口
- 生与死就在一瞬间
- 青春已从身边溜走
复制代码 以上几种算法都存在不易计算偏移量的先天缺陷,单独乱序输出时表现不错,但是若要同时计算偏移量,耗时将暴涨,此贴中另外三种在这方面则有优势:
常规算法就不提了,效率一般,也没什么艺术性。
读取自身输出作为输入的方案感觉已经无法再改进了,请见24楼terse代码。
最牛的应该是27楼neorobin的算法了,干净利落,浑然天成。 |