中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --
联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum
游客 | 登录 | 注册 | 会员 | 搜索 | 中国DOS联盟
中国DOS联盟论坛
现在时间是 2026-08-08 20:15
47,811 主题排行 / 349,895 发帖 / 今日 0 篇 / 48,253 会员排行
DOS批处理 & 脚本技术(批处理室) » [精彩][批处理字符出现次数统计]
可打印版本  23,758 / 41
第1楼 redtek 发表于 2006-11-29 08:26
金牌会员 发帖 1,147 积分 2,902
[精彩][批处理字符出现次数统计]
题目: 请求出下面变量中出现次数最多的单个字母和它们出现的次数。




解题要求: 只要是批处理,用任何方法均可~:)
      建议完全使用CMD Shell内部命令完成~:)

输出要求: (例:)

      a -- 10
      b -- 6
      ……
      出现次数最多的字母是: g
      ……等以此类推的样式(但不限于此输出样式)


关于答题: 旨交流批处理算法与技巧,共同进步~:)

评分处理: 最后由神一样的版主点评每一位答题者,并指导。同时大家相互交流:)
      越先答题以及精彩代码的网友,给于高分奖励~:)


      

[ Last edited by redtek on 2006-11-29 at 11:25 AM ]
第2楼 namejm 发表于 2006-11-29 08:52
荣誉版主 发帖 1,737 积分 5,226 来自 成都
  其实这个题目在论坛里是有现成的代码可供剽窃的,以前3742668兄曾经做过,我在无忧启动论坛里也帮别人解答过,暂时不提供代码,各位先讨论讨论^_^。
第3楼 vkill 发表于 2006-11-29 09:11
金牌会员 发帖 1,744 积分 4,103 来自 甘肃.临泽
建议 set "str=`-=\;',./~%!@#o^&*()_+{}|:<>?"abc123ABC00"

这样考虑特殊字符才有点难度哦

[ Last edited by vkill on 2006-11-30 at 04:43 AM ]
第4楼 electronixtar 发表于 2006-11-29 09:33
铂金会员 发帖 2,672 积分 7,493
Linux下有个命令叫 wc 哈哈哈哈哈
第5楼 zh159 发表于 2006-11-29 13:30
金牌会员 发帖 1,467 积分 3,687
玩一下^_^


[ Last edited by zxcv on 2006-11-29 at 01:31 AM ]
第6楼 redtek 发表于 2006-11-29 23:25
金牌会员 发帖 1,147 积分 2,902
zxcv兄5楼代码有意思~~欣赏~~~



上面先将 str 变量内的字符串 “adadfdfseffserfefsefseetsdg” “拆解” 成每个字符中间用空格隔开,为方便for单取字符传值使用~:)

(这个将连续字符串全部拆解成以空格隔开的单个字母的技巧很有意思~:)




当字符串已被 “拆解” 成每个字母均用空格隔开以后,通过for依次单取读出并以call语句后面带参数方式向 :Scan1 标签代码段传递数据。

这个时候 :Scan1 标签代码段内就可以使用 %1 的方式来取得 Call 过来的数据并处理~:)

(将连续字符串拆解成以空格隔开的单个字母是为了方便for取得单个字母)
(而for取以空格为分隔符的字符串是利用了 for 的 Delims 参数的默认值)

……

其它部分代码zxcv兄讲讲思路和原理吧? 



(最难得的是当 “远离” 了高级语言中可以随时调用的各种函数以后,(如字符串截取专用函数、统计等……)
(这样情况下,在批处理中使用内部命令与简单的语句同样可以完成思想的“传递”。)

(几乎一切都象是原始的操作,几个简单的语句分隔,几个Goto,几个SET……照样可以象模拟“底层”一样完成思想)

(这样的思考过程中,一切都是在没有现成函数支持的情况下,使用这些简单的命令复现这复杂的过程与梦想的实现)
(在这种过程中,可以体会并感受到“原始”与最接近“所能控置的最直接”的方式来复现批处理的美~~)


(昨天分都加光了,下午给zxcv把分补上~~:)
第7楼 无奈何 发表于 2006-11-29 23:52
荣誉版主 发帖 356 积分 1,338
cmd 下特殊字符是永远的痛,无力解决。
我也投递一帖,实在是没有更好的方法实现,笨办法凑合实现。


  1. @echo off
  2. setlocal ENABLEDELAYEDEXPANSION
  3. set str=adadfdfseffserfefsefseetsdg
  4. set /a m=0,n=0,l=0
  5. call :loop
  6. for /f "tokens=1,2 delims==" %%i in ('set 字符:') do (
  7. echo %%i=%%j
  8. if %%j GTR !l! set l=%%j & set m=%%i
  9. )
  10. echo.出现次数最多的%m%=%l%
  11. pause
  12. goto :EOF
  13. :loop
  14. call set m=%%str:~%n%,1%%
  15. if not defined m goto :EOF
  16. set /a "字符:%m%+=1"
  17. set /a n+=1
  18. goto loop
无奈何发表于 2006-11-29 10:50
第8楼 zh159 发表于 2006-11-30 00:08
金牌会员 发帖 1,467 积分 3,687
:Scan1
for %%i in (%exclude%) do if "%1"=="%%i" goto :eof
set exclude=%exclude% %1
call :Scan2 %1
goto :eof

利用“for %%i in (%exclude%) do if "%1"=="%%i" goto :eof”作为过滤相同的字符,有相同的返回“for %%i in (%str$%) do call :Scan1 %%i”进行下一个字符过滤,%exclude%里没有的新字符用“set exclude=%exclude% %1”加入(这是我在玩一个手机铃声排序时把选过的编号过滤)

:Scan2
for %%i in (%str$%) do if "%1"=="%%i" set /a %1+=1
echo %1 !%1!
goto :eof

过滤出来所用的字符逐一计算出现次数,用自身完成计算后“!%1!”延迟变量显示次数

之所以用“set /a %1+=1”,可以给后面单独为某个字符提供使用

如果只是单纯显示,改为:
:Scan1
for %%i in (%exclude%) do if "%1"=="%%i" goto :eof
set exclude=%exclude% %1
set N=
call :Scan2 %1
goto :eof

:Scan2
for %%i in (%str$%) do if "%1"=="%%i" set /a N+=1
echo %1 %N%
goto :eof

就可以不用延迟变量了
第9楼 redtek 发表于 2006-11-30 00:22
金牌会员 发帖 1,147 积分 2,902
无奈何版主和zxcv兄的代码闪亮着每一行思考的结晶~~~
甚是精彩~~
第10楼 ccwan 发表于 2006-11-30 00:30
金牌会员 发帖 1,160 积分 2,725 来自 河北廊坊
我帮redtek兄来加分吧!两位的注释很好,可惜偶没分了,以后吧。

[ Last edited by ccwan on 2006-11-30 at 12:35 AM ]
第11楼 zh159 发表于 2006-11-30 00:37
金牌会员 发帖 1,467 积分 3,687
借用无奈何版主一行脚本,只是还没有按字母排序^_^:

@echo off
setlocal EnableDelayedExpansion
set str=adadfdfseffserfefsefseetsdg

:loop
set str$=%str$% %str:~0,1%
set str=%str:~1%
if not "%str%" == "" goto loop

for %%i in (%str$%) do call :Scan1 %%i
echo 出现次数最多的:%max%=%maxN%
pause
exit

:Scan1
for %%i in (%exclude%) do if "%1"=="%%i" goto :eof
set exclude=%exclude% %1
call :Scan2 %1
goto :eof

:Scan2
for %%i in (%str$%) do if "%1"=="%%i" set /a %1+=1
if !%1! GTR !maxN! set maxN=!%1! & set max=%1
echo 字符:%1=!%1!
goto :eof
第12楼 vkill 发表于 2006-11-30 00:44
金牌会员 发帖 1,744 积分 4,103 来自 甘肃.临泽
如果结合sed grep就简单多了显得
第13楼 redtek 发表于 2006-11-30 00:46
金牌会员 发帖 1,147 积分 2,902
vkill用sed做一个吧~:)
第14楼 vkill 发表于 2006-11-30 00:53
金牌会员 发帖 1,744 积分 4,103 来自 甘肃.临泽
Originally posted by redtek at 2006-11-30 00:46:
vkill用sed做一个吧~:)

呵呵~用 grep -c 可以,因为不用三方工具的话特殊字符根本没有办法,我认为
第15楼 redtek 发表于 2006-11-30 02:30
金牌会员 发帖 1,147 积分 2,902
我也来一段儿,借用zxcv兄的 :loop 空格间隔字母的代码段一用~:)

1 2 3  下一页
[ 联系联盟系统管理团队 - 中国DOS联盟 - 标准版 ]
Sponsored by ifanr Inc | © 2001–2023