[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
这只是另一种思路而已,总有适合它的背景。上次生命游戏给我的教训是变量越多速度越慢,以至于后来一个循环耗时前后居然相差了十几倍,所以现在写代码时总会考虑变量的增加对效率的影响

TOP

本帖最后由 caruko 于 2011-4-22 14:07 编辑

这个在随机排序大量文本的时候是不错,没有临时,没有大量变量,但是效率有点低。

1:echo更耗时,增加了echo次数。
2:sort 本身也是很耗内存的,sort /? 帮助命令看一下就能了解。N个排序对象,在SORT里,产生N个变量用来存放是至少的。set的机制不了解,但似乎在变量存放的时候就是有序的。
3:“ | sort + for”,echo完所有内容进入管道后,SORT才开始排序,SORT排序完并输出所有内容后,FOR开始读取。 所以耗时成倍增加。

TOP

本帖最后由 zm900612 于 2011-4-22 13:21 编辑

不一样吧,我的思路是直接分析自身输出,不需要定义大量变量
要不是字数已经超过31,用tokens+random来截取估计是最快的办法了

TOP

楼上这个,方法跟我那个差不多吧,只是我用set 排序,你用sort。

最早的时候,我想过一种类似洗扑克牌的乱序方法。

1:随机将后一个字符放在前一个字符的前面或者后面,组合成新的字符串。
2:将新字符串再一次洗牌,循环随机20-40次。(估计了一下40个字符20次差不多能做到足够乱序了)

只是思路的一种吧,细想了一下,发现效率不怎么高,就没继续了。

TOP

另一种乱序输出思路:
  1. @echo off&setlocal enabledelayedexpansion&2>nul 3>nul echo %time%
  2. for /f "skip=14 useback" %%a in ("%~0") do set str=!str!%%a
  3. if "%1"==":" (
  4. for /l %%a in (0 1 39) do echo !random!@!str:~%%a,1!@%%a
  5. exit /b
  6. )
  7. for /f "tokens=2,3 delims=@" %%a in ('%0 : ^|sort') do (
  8. set echo=!echo!%%a
  9. set /a x=n%%8-%%b%%8,y=n/8-%%b/8,n+=1,m=n%%8,1/m||set echo=!echo!,
  10. set "xy=!xy!   !x!: !y!   "
  11. )
  12. for %%a in (!echo!) do echo %%a
  13. echo %xy: -=-%
  14. echo %time%&pause>nul&exit
  15. 我们去北大踢球吧
  16. 快上那儿等着信号
  17. 你不能离开大门口
  18. 生与死就在一瞬间
  19. 青春已从身边溜走
复制代码

TOP

14楼的思路是比较巧妙,但美中不足就是set/p输出影响了效率。。。

下面给出一种乱序的方法(先替换a为#,再替换b为a,最后替换#为b从而达到a、b互换的效果):
  1. @echo off&setlocal enabledelayedexpansion
  2. set "#0=&echo,"
  3. for /f "skip=22" %%a in (%~0) do set "str=!str!%%a"
  4. for /l %%a in (0,1,39) do (
  5.     set /a a=!random!%%40
  6.     for %%b in (!a!) do (
  7.         set "a=!str:~%%b,1!"
  8.         for %%b in ("!str:~%%a,1!") do (
  9.             for %%c in (!a!) do (
  10.                 set "str=!str:%%c=#!"
  11.                 set "str=!str:%%~b=%%c!"
  12.                 set "str=!str:#=%%~b!"
  13.             )
  14.         )
  15.     )
  16. )
  17. for /l %%a in (0,1,39) do (
  18.     set /a "a=(%%a+1)%%8"
  19.     for %%b in (!a!) do set "var=!var!!str:~%%a,1!!#%%b!"
  20. )
  21. echo %var%
  22. pause>nul&goto :eof
  23. 我们去北大踢球吧
  24. 快上那儿等着信号
  25. 你不能离开大门口
  26. 生与死就在一瞬间
  27. 青春已从身边溜走
复制代码
 注:因为每次都是两个汉字互换位置(有时可能是自己换自己),所以偏移量的计算会要借助临时文件来实现。
***共同提高***

TOP

其实我本意只是想提出一个随机取值的思路,因为常规思路要定义大量变量,很容易影响P的整体性能,不过话说回来,估计那个办法大概早有人发明了吧...

TOP

本帖最后由 zm900612 于 2011-4-23 22:24 编辑
10# zm900612
下面是阁下代码的一次运行结果:
就死门离们上吧间
死生就着们踢离大
开我不离儿去去儿
快等北快北我去快
我大大们去们们我
batman 发表于 2011-4-21 18:59

当时只是为了表达思路,几分钟搞出来也没测试就回了,所以没发现这个问题...出错原因是漏了"",而且后来发现给定的文字中有重字,所以不能用变量替换取巧。
原帖就不改了,发一下新代码,这回是调试过无误的:
  1. @echo off&setlocal enabledelayedexpansion&echo %time%
  2. for /f "skip=14 useback" %%a in ("%~0") do set str=!str!%%a
  3. for /l %%a in (1 1 39) do set .!str:~%%a,1!=%%a
  4. for /l %%a in (40 -1 1) do (
  5. set /a "ra=!random!%%%%a","m=~-%%a%%8",n=ra+1
  6. for %%b in ("str:~!ra!,1") do (
  7. set /a "p=(40-%%a)-.!%%~b!","x=(40-%%a)%%8-.!%%~b!%%8","y=(40-%%a)/8-.!%%~b!/8"
  8. set "echo=!echo!!%%~b!"&set "xy=!xy!   !x!: !y!   "
  9. for /f "tokens=1* delims=@" %%c in ("!ra!@!n!") do set str=!str:~0,%%~c!!str:~%%~d!
  10. )
  11. )
  12. for /l %%a in (0 8 32) do echo !echo:~%%a,8!
  13. echo %xy: -=-%
  14. echo %time%&pause>nul&exit
  15. 我们去北大踢球吧
  16. 快上那儿等着信号
  17. 你不能离开大门口
  18. 生与死就在一瞬间
  19. 青春已从身边溜走
复制代码
优化了一下,用时减少一半
1

评分人数

    • batman: 好!思路绝了!PB + 20

TOP

本帖最后由 batman 于 2011-4-21 22:34 编辑

期待更多的解。。。。
  1. @echo off&setlocal enabledelayedexpansion
  2. for /l %%a in (101,1,140) do set "a=%%a"&set "code=!code!#!a:~1!#"
  3. set /a num=40&set "#0=&echo,"
  4. for /f "skip=23" %%a in (%~0) do (
  5.     set "str=%%a"&set /a h+=1
  6.     for /l %%a in (0,1,7) do (
  7.         set /a a=!random!%%num,num-=1,a*=4
  8.         for %%b in (!a!) do (
  9.             for %%b in ("!code:~%%b,4!") do (
  10.                 set "a=%%~b"&set "a=!a:#=!"&set "code=!code:%%~b=!"
  11.                 set /a a=1!a!%%100,hm=a/8+1-h,"lm=(a-1)%%8-%%a"
  12.                 for %%b in (h l) do if "!%%bm:-=!" equ "!%%bm!" set "%%bm= !%%bm!"
  13.                 set "_!a!=!str:~%%a,1!"&set ".!a!=!hm!:!lm!"            
  14.             )
  15.         )
  16.     )
  17. )
  18. for /l %%a in (1,1,40) do (
  19.     set "a=      !.%%a!"&set /a b=%%a%%8
  20.     for %%b in (!b!) do set "var=!var!!_%%a!!#%%b!"&set "var1=!var1!!a:~-6!!#%%b!"
  21. )
  22. echo %var%&echo %var1%
  23. pause>nul&goto :eof
  24. 我们去北大踢球吧
  25. 快上那儿等着信号
  26. 你不能离开大门口
  27. 生与死就在一瞬间
  28. 青春已从身边溜走
复制代码
***共同提高***

TOP

10# zm900612
下面是阁下代码的一次运行结果:
就死门离们上吧间
死生就着们踢离大
开我不离儿去去儿
快等北快北我去快
我大大们去们们我
***共同提高***

TOP

难道题意不是已知的。。。
***共同提高***

TOP

特殊情况有特殊解法:
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "skip=11 useback" %%a in ("%~0") do set str=!str!%%a
  3. for /l %%a in (40 -1 1) do (
  4. set /a ra=!random!%%%%a,m=~-%%a%%8
  5. for %%b in (!ra!) do (
  6. set /p=!str:~%%b,1!<nul
  7. for %%c in (!str:~%%b,1!) do set str=!str:%%c=!
  8. )
  9. if !m!==0 echo;
  10. )
  11. pause>nul&exit
  12. 我们去北大踢球吧
  13. 快上那儿等着信号
  14. 你不能离开大门口
  15. 生与死就在一瞬间
  16. 青春已从身边溜走
复制代码

TOP

已知的  我直接40个  ECHO

TOP

本帖最后由 batman 于 2011-4-21 11:41 编辑

乱序思路:
  因为原始文本是5行共40个汉字,所以设置一个code变量,其值为010203...383940。然后每读取一个汉字随机取一次值(初始是对40随机取位置的值),同时将根据随机取得的位置值查找code中对应的值并将汉字存进这个值变量,再从code中删除这个值并将总数值减一,最后所有的汉字都被乱序并储存到了01-40的变量中。
***共同提高***

TOP

已知行数和字符数 是否可以再简化点 个人感觉 乱序排列的SET效率并不很理想
两个边字的问题 可以放入的吧 因乱序后还是可以对应的哦

TOP

返回列表