|
redtek
金牌会员
     
积分 2902
发帖 1147
注册 2006-9-21
状态 离线
|
『楼 主』:
[精彩][批处理字符出现次数统计]
使用 LLM 解释/回答一下
题目: 请求出下面变量中出现次数最多的单个字母和它们出现的次数。
set str=adadfdfseffserfefsefseetsdg
解题要求: 只要是批处理,用任何方法均可~:)
建议完全使用CMD Shell内部命令完成~:)
输出要求: (例:)
a -- 10
b -- 6
……
出现次数最多的字母是: g
……等以此类推的样式(但不限于此输出样式)
关于答题: 旨交流批处理算法与技巧,共同进步~:)
评分处理: 最后由神一样的版主点评每一位答题者,并指导。同时大家相互交流:)
越先答题以及精彩代码的网友,给于高分奖励~:)
Last edited by redtek on 2006-11-29 at 11:25 AM ]
### 代码实现
```batch
@echo off
setlocal enabledelayedexpansion
set "str=adadfdfseffserfefsefseetsdg"
set "chars=a b c d e f g h i j k l m n o p q r s t u v w x y z"
set max_count=0
set max_char=
for %%c in (%chars%) do (
set count=0
for /l %%i in (0,1,100) do (
set "char=!str:~%%i,1!"
if "!char!"=="%%c" (
set /a count+=1
)
)
if !count! gtr !max_count! (
set max_count=!count!
set max_char=%%c
)
)
echo 出现次数最多的字母是:%max_char%,出现次数:%max_count%
endlocal
```
### 代码解释
1. `@echo off`:关闭命令回显,使脚本执行时不显示命令本身。
2. `setlocal enabledelayedexpansion`:启用延迟环境变量扩展,以便在循环中正确获取更新后的变量值。
3. `set "str=adadfdfseffserfefsefseetsdg"`:设置要处理的字符串。
4. `set "chars=a b c d e f g h i j k l m n o p q r s t u v w x y z"`:定义所有可能的字母。
5. `for %%c in (%chars%) do`:遍历每个字母。
6. `set count=0`:初始化每个字母的计数为0。
7. `for /l %%i in (0,1,100) do`:循环遍历字符串的每个字符(假设字符串长度不超过100)。
8. `set "char=!str:~%%i,1!"`:获取字符串中指定位置的字符。
9. `if "!char!"=="%%c" ( set /a count+=1 )`:如果当前字符与遍历的字母相同,计数加1。
10. `if !count! gtr !max_count! ( set max_count=!count! & set max_char=%%c )`:如果当前字母的计数大于最大计数,更新最大计数和对应的字母。
11. `echo 出现次数最多的字母是:%max_char%,出现次数:%max_count%`:输出出现次数最多的字母及其次数。
12. `endlocal`:结束局部环境,恢复之前的环境变量状态。
|

Redtek,一个永远在网上流浪的人……
_.,-*~'`^`'~*-,.__.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._ |
|
2006-11-29 08:26 |
|
|
namejm
荣誉版主
       batch fan
积分 5226
发帖 1737
注册 2006-3-10 来自 成都
状态 离线
|
『第 2 楼』:
使用 LLM 解释/回答一下
其实这个题目在论坛里是有现成的代码可供剽窃的,以前3742668兄曾经做过,我在无忧启动论坛里也帮别人解答过,暂时不提供代码,各位先讨论讨论^_^。
Actually, there is ready-made code available for plagiarism in this topic in the forum. Brother 3742668 did it before, and I also helped others answer in the Wuyou Boot Forum. I won't provide the code for now. You all can discuss it first ^_^.
|

尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。 |
|
2006-11-29 08:52 |
|
|
vkill
金牌会员
     
积分 4103
发帖 1744
注册 2006-1-20 来自 甘肃.临泽
状态 离线
|
『第 3 楼』:
使用 LLM 解释/回答一下
建议 set "str=`-=\;',./~%!@#o^&*()_+{}|:<>?"abc123ABC00"
这样考虑特殊字符才有点难度哦
Last edited by vkill on 2006-11-30 at 04:43 AM ]
Suggestion: set "str=`-=\;',./~%!@#o^&*()_+{}|:<>?"abc123ABC00"
This kind of consideration for special characters is a bit challenging, oh
Last edited by vkill on 2006-11-30 at 04:43 AM ]
|
|
2006-11-29 09:11 |
|
|
electronixtar
铂金会员
      
积分 7493
发帖 2672
注册 2005-9-2
状态 离线
|
『第 4 楼』:
使用 LLM 解释/回答一下
Linux下有个命令叫 wc 哈哈哈哈哈
There is a command called wc in Linux haha ha ha ha
|

C:\>BLOG http://initiative.yo2.cn/
C:\>hh.exe ntcmds.chm::/ntcmds.htm
C:\>cmd /cstart /MIN "" iexplore "about:<bgsound src='res://%ProgramFiles%\Common Files\Microsoft Shared\VBA\VBA6\vbe6.dll/10/5432'>" |
|
2006-11-29 09:33 |
|
|
zh159
金牌会员
     
积分 3687
发帖 1467
注册 2005-8-8
状态 离线
|
『第 5 楼』:
使用 LLM 解释/回答一下
玩一下^_^
@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
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
echo %1 !%1!
goto :eof
Last edited by zxcv on 2006-11-29 at 01:31 AM ]
Have a try^_^
@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
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
echo %1 !%1!
goto :eof
Last edited by zxcv on 2006-11-29 at 01:31 AM ]
此帖被 +21 点积分 点击查看详情 评分人:【 ccwan 】 | 分数: +3 | 时间:2006-11-30 00:30 | 评分人:【 lxmxn 】 | 分数: +5 | 时间:2006-11-30 00:55 | 评分人:【 namejm 】 | 分数: +4 | 时间:2006-11-30 01:55 | 评分人:【 pengfei 】 | 分数: +4 | 时间:2006-11-30 03:31 | 评分人:【 redtek 】 | 分数: +5 | 时间:2006-12-30 07:03 |
|
|
|
2006-11-29 13:30 |
|
|
redtek
金牌会员
     
积分 2902
发帖 1147
注册 2006-9-21
状态 离线
|
『第 6 楼』:
使用 LLM 解释/回答一下
zxcv兄5楼代码有意思~~欣赏~~~
set str$=%str$% %str:~0,1%
set str=%str:~1%
……
上面先将 str 变量内的字符串 “adadfdfseffserfefsefseetsdg” “拆解” 成每个字符中间用空格隔开,为方便for单取字符传值使用~:)
(这个将连续字符串全部拆解成以空格隔开的单个字母的技巧很有意思~:)
for %%i in (%str$%) do call :Scan1 %%i
当字符串已被 “拆解” 成每个字母均用空格隔开以后,通过for依次单取读出并以call语句后面带参数方式向 :Scan1 标签代码段传递数据。
这个时候 :Scan1 标签代码段内就可以使用 %1 的方式来取得 Call 过来的数据并处理~:)
(将连续字符串拆解成以空格隔开的单个字母是为了方便for取得单个字母)
(而for取以空格为分隔符的字符串是利用了 for 的 Delims 参数的默认值)
……
其它部分代码zxcv兄讲讲思路和原理吧?
(最难得的是当 “远离” 了高级语言中可以随时调用的各种函数以后,(如字符串截取专用函数、统计等……)
(这样情况下,在批处理中使用内部命令与简单的语句同样可以完成思想的“传递”。)
(几乎一切都象是原始的操作,几个简单的语句分隔,几个Goto,几个SET……照样可以象模拟“底层”一样完成思想)
(这样的思考过程中,一切都是在没有现成函数支持的情况下,使用这些简单的命令复现这复杂的过程与梦想的实现)
(在这种过程中,可以体会并感受到“原始”与最接近“所能控置的最直接”的方式来复现批处理的美~~)
(昨天分都加光了,下午给zxcv把分补上~~:)
Brother zxcv, the code on floor 5 is interesting~ Appreciate it~~~
set str$=%str$% %str:~0,1%
set str=%str:~1%
……
The above first "breaks down" the string in the str variable "adadfdfseffserfefsefseetsdg" into individual characters separated by spaces, for the convenience of the for loop to take character values one by one~ : )
(This technique of breaking down a continuous string into individual letters separated by spaces is very interesting~ : )
for %%i in (%str$%) do call :Scan1 %%i
When the string has been "broken down" into individual letters each separated by a space, it reads them one by one through for and passes the data to the :Scan1 label code segment in the form of a call statement with parameters.
At this time, the :Scan1 label code segment can use the %1 method to get the data called over and process it~ : )
(The purpose of breaking down the continuous string into individual letters separated by spaces is to facilitate the for to get individual letters)
(And for getting strings with spaces as delimiters makes use of the default value of the for Delims parameter)
……
Brother zxcv, please talk about the ideas and principles of the other parts of the code?
(The most difficult thing is when "away from" the various functions that can be called at any time in high-level languages, (such as special functions for string interception, statistics, etc......)
(In this case, using internal commands and simple statements in batch processing can also complete the "transmission" of ideas. )
(Almost everything is like primitive operations, a few simple statement separations, a few Goto, a few SET...... can still complete the idea like simulating the "underlying" level. )
(In such a thinking process, everything is under the condition of no ready-made function support, using these simple commands to reproduce this complex process and the realization of the dream)
(In this process, you can experience and feel the "primitive" and the most direct way to reproduce the beauty of batch processing)
(All the points were given away yesterday, and I will make up the points for zxcv this afternoon~ : )
此帖被 +1 点积分 点击查看详情 评分人:【 meiko 】 | 分数: +1 | 时间:2007-4-22 05:07 |
|
|

Redtek,一个永远在网上流浪的人……
_.,-*~'`^`'~*-,.__.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._ |
|
2006-11-29 23:25 |
|
|
无奈何
荣誉版主
      
积分 1338
发帖 356
注册 2005-7-15
状态 离线
|
 『第 7 楼』:
使用 LLM 解释/回答一下
cmd 下特殊字符是永远的痛,无力解决。
我也投递一帖,实在是没有更好的方法实现,笨办法凑合实现。
- @echo off
- setlocal ENABLEDELAYEDEXPANSION
- set str=adadfdfseffserfefsefseetsdg
- set /a m=0,n=0,l=0
- call :loop
- for /f "tokens=1,2 delims==" %%i in ('set 字符:') do (
- echo %%i=%%j
- if %%j GTR !l! set l=%%j & set m=%%i
- )
- echo.出现次数最多的%m%=%l%
- pause
- goto :EOF
- :loop
- call set m=%%str:~%n%,1%%
- if not defined m goto :EOF
- set /a "字符:%m%+=1"
- set /a n+=1
- goto loop
无奈何发表于 2006-11-29 10:50
Special characters in cmd are always a headache, and there's no way to solve them.
I also posted a thread. There's really no better way to implement it, so I use a crude method to make do.
- @echo off
- setlocal ENABLEDELAYEDEXPANSION
- set str=adadfdfseffserfefsefseetsdg
- set /a m=0,n=0,l=0
- call :loop
- for /f "tokens=1,2 delims==" %%i in ('set 字符:') do (
- echo %%i=%%j
- if %%j GTR !l! set l=%%j & set m=%%i
- )
- echo.出现次数最多的%m%=%l%
- pause
- goto :EOF
- :loop
- call set m=%%str:~%n%,1%%
- if not defined m goto :EOF
- set /a "字符:%m%+=1"
- set /a n+=1
- goto loop
Posted by 无奈何 on November 29, 2006 at 10:50
此帖被 +27 点积分 点击查看详情 评分人:【 ccwan 】 | 分数: +3 | 时间:2006-11-30 00:30 | 评分人:【 lxmxn 】 | 分数: +5 | 时间:2006-11-30 00:56 | 评分人:【 namejm 】 | 分数: +4 | 时间:2006-11-30 02:40 | 评分人:【 pengfei 】 | 分数: +4 | 时间:2006-11-30 03:32 | 评分人:【 IceCrack 】 | 分数: +4 | 时间:2006-11-30 08:14 | 评分人:【 redtek 】 | 分数: +5 | 时间:2006-12-30 07:03 | 评分人:【 26933062 】 | 分数: +2 | 时间:2007-1-10 09:35 |
|
|

☆开始\运行 (WIN+R)☆
%ComSpec% /cset,=何奈无── 。何奈可无是原,事奈无做人奈无&for,/l,%i,in,(22,-1,0)do,@call,set/p= %,:~%i,1%<nul&ping/n 1 127.1>nul
|
|
2006-11-29 23:52 |
|
|
zh159
金牌会员
     
积分 3687
发帖 1467
注册 2005-8-8
状态 离线
|
 『第 8 楼』:
使用 LLM 解释/回答一下
: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
就可以不用延迟变量了
:Scan1
for %%i in (%exclude%) do if "%1"=="%%i" goto :eof
set exclude=%exclude% %1
call :Scan2 %1
goto :eof
Using "for %%i in (%exclude%) do if "%1"=="%%i" to filter out the same characters, if there is a duplicate, return "for %%i in (%str$%) do call :Scan1 %%i" to filter the next character. The new character not in %exclude% is added with "set exclude=%exclude% %1" (this is when I was sorting mobile phone ringtones to filter the selected numbers)
:Scan2
for %%i in (%str$%) do if "%1"=="%%i" set /a %1+=1
echo %1 !%1!
goto :eof
The filtered characters are calculated one by one for the number of occurrences. After self-calculation, "!%1!" is used with delayed variables to display the number of occurrences
The reason for using "set /a %1+=1" is to provide usage for a single character later
If you just want to display, change it to:
: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
You can do without delayed variables
|
|
2006-11-30 00:08 |
|
|
redtek
金牌会员
     
积分 2902
发帖 1147
注册 2006-9-21
状态 离线
|
『第 9 楼』:
使用 LLM 解释/回答一下
无奈何版主和zxcv兄的代码闪亮着每一行思考的结晶~~~
甚是精彩~~
Helplessly, the code of the moderator and brother zxcv shines with the crystallization of every line of thinking ~~~
It's really wonderful ~~
|

Redtek,一个永远在网上流浪的人……
_.,-*~'`^`'~*-,.__.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._ |
|
2006-11-30 00:22 |
|
|
ccwan
金牌会员
     
积分 2725
发帖 1160
注册 2006-9-23 来自 河北廊坊
状态 离线
|
『第 10 楼』:
使用 LLM 解释/回答一下
我帮redtek兄来加分吧!两位的注释很好,可惜偶没分了,以后吧。
Last edited by ccwan on 2006-11-30 at 12:35 AM ]
I'll help Brother redtek add points! The two of you have great comments. Unfortunately, I don't have points right now. Next time then.
Last edited by ccwan on 2006-11-30 at 12:35 AM ]
|

三人行,必有吾师焉。 学然后知不足,教然后知困,然后能自强也。 |
|
2006-11-30 00:30 |
|
|
zh159
金牌会员
     
积分 3687
发帖 1467
注册 2005-8-8
状态 离线
|
 『第 11 楼』:
使用 LLM 解释/回答一下
借用无奈何版主一行脚本,只是还没有按字母排序^_^:
@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
Borrowing the script from Moderator Wunaike, but it hasn't been sorted alphabetically yet ^_^:
@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 The most frequent occurrence: %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 Character: %1=!%1!
goto :eof
|
|
2006-11-30 00:37 |
|
|
vkill
金牌会员
     
积分 4103
发帖 1744
注册 2006-1-20 来自 甘肃.临泽
状态 离线
|
『第 12 楼』:
使用 LLM 解释/回答一下
如果结合sed grep就简单多了显得
If combined with sed grep, it is much simpler and appears
|
|
2006-11-30 00:44 |
|
|
redtek
金牌会员
     
积分 2902
发帖 1147
注册 2006-9-21
状态 离线
|
『第 13 楼』:
使用 LLM 解释/回答一下
vkill用sed做一个吧~:)
vkill use sed to make one~ :)
|

Redtek,一个永远在网上流浪的人……
_.,-*~'`^`'~*-,.__.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._ |
|
2006-11-30 00:46 |
|
|
vkill
金牌会员
     
积分 4103
发帖 1744
注册 2006-1-20 来自 甘肃.临泽
状态 离线
|
『第 14 楼』:
使用 LLM 解释/回答一下
Originally posted by redtek at 2006-11-30 00:46:
vkill用sed做一个吧~:)
呵呵~用 grep -c 可以,因为不用三方工具的话特殊字符根本没有办法,我认为
Originally posted by redtek at 2006-11-30 00:46:
vkill make one with sed~:)
Hehe~ grep -c can be used, because without using third-party tools, special characters can't be handled at all, I think
|
|
2006-11-30 00:53 |
|
|
redtek
金牌会员
     
积分 2902
发帖 1147
注册 2006-9-21
状态 离线
|
『第 15 楼』:
使用 LLM 解释/回答一下
我也来一段儿,借用zxcv兄的 :loop 空格间隔字母的代码段一用~:)
@echo off
set str=adadfdfseffserfefsefseetsdg
:loop
set str$=%str$% %str:~0,1% && set str=%str:~1%
if not "%str%" == "" goto loop
call :start %str$%
set . & goto :eof
:start
if == ( goto :eof ) else ( set /a .%1+=1 )
shift
goto :start
I also come to a section, borrow the code segment with the space-separated letters of zxcv brother's :loop ~:)
@echo off
set str=adadfdfseffserfefsefseetsdg
:loop
set str$=%str$% %str:~0,1% && set str=%str:~1%
if not "%str%" == "" goto loop
call :start %str$%
set . & goto :eof
:start
if == ( goto :eof ) else ( set /a .%1+=1 )
shift
goto :start
此帖被 +10 点积分 点击查看详情 评分人:【 namejm 】 | 分数: +4 | 时间:2006-11-30 02:48 | 评分人:【 zh159 】 | 分数: +4 | 时间:2006-11-30 03:00 | 评分人:【 youxi01 】 | 分数: +2 | 时间:2006-11-30 06:08 |
|
|

Redtek,一个永远在网上流浪的人……
_.,-*~'`^`'~*-,.__.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._ |
|
2006-11-30 02:30 |
|