找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 42596|回复: 24

【练习-068】批处理号码筛选练习

[复制链接]
发表于 2012-2-29 10:07:47 | 显示全部楼层 |阅读模式
本帖最后由 batman 于 2012-2-29 10:25 编辑

出题目的:
  强化新手对字符截取和if判断的理解
加分原则:
  满分20分,其中解题思路7分,思路描述3分,代码运行效率4分,代码简洁4分,书写规范2分,
  本帖内同一id累计加分不超过40分(请大家在加分时注意)
  如管理层和技术组解题分值减半
  跟帖讨论的视情况加分,最高不超过10分
相关要求:
  请新手自觉独立解题不得抄袭别人代码(可以借鉴)
  请测试代码成功后再发帖
  请最好附上思路说明
题目如下:
  编写批处理代码对所有4位号码进行筛选归类,归类原则如下:
    一类 8888
    二类 x888 aaaa abcd
    三类 xx88 xaaa xabc aabb abab
    四类 xxx8 xxaa abba
    五类 其余的号码
    其中
      x表示不等于其后一位数值的任意数值
                 aaaa为除8888以外的4连号如0000 xaaa xxaa以此类推
      abc abcd代表顺子如123 321 1234 4321
      aabb为形如1122的号码 abab为形如1212的号码 abba为形如1221的号码
发表于 2012-2-29 10:12:46 | 显示全部楼层

穷举法 挨个试..

本帖最后由 jinzeyu 于 2012-2-29 11:25 编辑
  1. @echo off&setlocal enableDelayedExpansion&set str=0123456789876543210&set "ml=是三类&goto:eof"&for /l %%i in (1000,1,9999) do call:main %%i
  2. :main
  3. set i=%1
  4. set i1=%i:~0,1%
  5. set i2=%i:~1,1%
  6. set i3=%i:~2,1%
  7. set i4=%i:~3,1%
  8. if "%i%"=="8888" echo %1%ml:三=一%
  9. if "%i:~1%"=="888" echo %1%ml:三=二%
  10. if "%i:~2%"=="88" echo %1%ml%
  11. if "%i:~3%"=="8" echo %1%ml:三=四%
  12. if "%i:~2% %i2%"=="%i:~0,2% %i3%" echo %1%ml:三=二%
  13. if "%i:~1,2%"=="%i:~3%%i:~3%" echo %1%ml%
  14. if "%i:~3%"=="%i3%" echo %1%ml:三=四%
  15. for /l %%j in (0,1,16) do (
  16. if "%1"=="!str:~%%j,4!" echo %1%ml:三=二%
  17. if "%i:~1%"=="!str:~%%j,3!" echo %1%ml%
  18. if "%i:~0,3%"=="!str:~%%j,3!" echo %1%ml%)
  19. if "%i1%%i2%"=="%i4%%i3%" if not "%i1%"=="%i2%" echo %1%ml:一=四%
  20. if "%i1%%i3%"=="%i2%%i4%" if not "%i2%"=="%i4%" echo %1%ml%
  21. if "%i:~0,2%"=="%i:~2%" if not "%i1%"=="%i2%" echo %1%ml%
  22. echo %1是五类
复制代码

评分

参与人数 1PB +11 收起 理由
batman + 11 书写有点不规范

查看全部评分

发表于 2012-2-29 10:16:39 | 显示全部楼层
有几个问题:
  如7378算四类吗
  如1331算四类吗
  如1313算三类吗
  如1133算三类吗
 楼主| 发表于 2012-2-29 10:22:31 | 显示全部楼层
回复 3# jinzeyu


    是的,顶楼应该描述得很清楚吧。。。
发表于 2012-2-29 10:25:44 | 显示全部楼层
回复 4# batman


    哦 我还以为也是连续数字呢
发表于 2012-2-29 14:10:49 | 显示全部楼层
利用for的嵌套,写出指定特征形式的数字,再排除不正确的。。。。。
思路不清晰,排除得我快累死了。。。。。还不知道对不对。。。。。。。
以后再也不做这种题了。。。。。。。。。
  1. @echo off&SetLocal EnableDelayEdexpansion&cd /d "%~dp0"
  2. if exist "第四类" goto :1

  3. set "num1=0123456789"
  4. set "num2=9876543210"
  5. (for /l %%a in (0 1 9) do (
  6.   if "%%a" leq "5" echo !num1:~%%a,4! & echo !num2:~%%a,4!
  7.   if not "%%a"=="8" (
  8.     echo %%a%%a%%a%%a
  9.     echo %%a888
  10.   )
  11. ))>第二类

  12. (for /l %%a in (0 1 9) do (

  13.   for /l %%b in (0 1 9) do (
  14.     if not "%%b"=="8" (echo %%a%%b88)
  15.     if not "%%b"=="%%a" (
  16.       if not "%%b"=="8"  echo %%a%%b%%b%%b
  17.       set /a "n=%%a-1"
  18.       call set "n1=%%num1:~!n!,1%%"
  19.       call set "n2=%%num2:~!n!,1%%"
  20.       if %%a leq 6 if not "%%b"=="!n1!" if not "%%b"=="!num1:~%%a,1!"  echo  %%

  21. b!num1:~%%a,3!
  22.       if %%a leq 6 if not "%%b"=="!n2!" if not "%%b"=="!num2:~%%a,1!"  echo  %%

  23. b!num2:~%%a,3!
  24.       echo %%a%%a%%b%%b
  25.       echo %%a%%b%%a%%b
  26.     )
  27.   )
  28. ))>第三类

  29. (for /l %%a in (0 1 9) do (
  30.   for /l %%b in (0 1 9) do (
  31.     if not "%%b"=="%%a"  echo %%a%%b%%b%%a
  32.     for /l %%c in (0 1 9) do (
  33.       if not "%%a"=="%%b" if not "%%b"=="%%c"  if not "%%c"=="8" (
  34.          if not "%%b%%c"=="67"  echo  %%a%%b%%c8
  35.          echo %%a%%b%%c%%c
  36.       )
  37.     )
  38.   )
  39. ))>第四类


  40. :1
  41. set /p "number=input:"
  42. if "!number!"=="8888" echo 第一类 & goto :1

  43. findstr  /m  "!number!"   第三类 第二类 第四类 || echo 第五类
  44. echo -------------------------------------------------
  45. goto :1
复制代码

评分

参与人数 1PB +4 收起 理由
batman + 4 参与就是好的

查看全部评分

 楼主| 发表于 2012-2-29 15:19:20 | 显示全部楼层
回复 6# QIAOXINGXING


    兄弟是不是想复杂了,这个思路应该很好理的。。。
发表于 2012-2-29 16:09:22 | 显示全部楼层
回复 7# batman

估计是,,,,,,,坐等答案公布。。。。。。
发表于 2012-3-4 11:14:27 | 显示全部楼层
不知道有没有简洁的代码 我的太复杂了...一堆if
发表于 2012-3-4 23:11:56 | 显示全部楼层
4个 FOR 循环 省了字符截取 一味的 IF IF
 楼主| 发表于 2012-3-27 09:32:16 | 显示全部楼层
本帖最后由 batman 于 2012-3-29 09:05 编辑

参考答案

  1. @echo off&setlocal enabledelayedexpansion
  2. (for /l %%a in (10000,1,19999) do (
  3.   set "str=%%a"&set "str=!str:~1!"&set "flag=五类"
  4.   set /a a=!str:~,1!,b=!str:~1,1!,c=!str:~2,1!,d=!str:~-1!,b1=b+1,b2=b-1,c1=c+2,c2=c-2,d1=d+3,d2=d-3
  5.   if "!d!" equ "8" set "flag=四类"
  6.   if "!c!" equ "!d!" set "flag=四类"
  7.   if "!a!!b!" equ "!d!!c!" set "flag=四类"
  8.   if "!c!!d!" equ "88" set "flag=三类"
  9.   for %%a in (!b!) do if "!str:%%a=!" equ "!a!" set "flag=三类"
  10.   if "!a!!b!" equ "!c!!d!" set "flag=三类"
  11.   if "!a!!c!" equ "!b!!d!" set "flag=三类"
  12.   for %%a in (1 2) do if "!b%%a!!c%%a!!d%%a!" equ "!b%%a!!b%%a!!b%%a!" set "flag=三类"
  13.   if "!b!!c!!d!" equ "888" set "flag=二类"
  14.   for %%a in (!a!) do if "!str:%%a=!" equ "" set "flag=二类"
  15.   for %%a in (1 2) do if "!a!!b%%a!!c%%a!!d%%a!" equ "!a!!a!!a!!a!" set "flag=二类"
  16.   if "!str!" equ "8888" set "flag=一类"
  17.   echo !flag!        !str!
  18. ))>list.txt
  19. start list.txt
复制代码
 楼主| 发表于 2012-3-27 09:56:24 | 显示全部楼层
本帖最后由 batman 于 2012-3-27 10:07 编辑

在此对本题进行一下说明:
  其实本题真的不难,主要还在于判断的技巧性。总的来说有两种筛选的方法,一种是由低级向高级的筛选法,
我们就叫做正向筛选法吧(如11楼)。对任一个四位数我们先将它暂定为五类(set "flag=五类"),然后逐步
判断它是不是符合四、三、二、一类的标准,如果符合标准,flag变量就被重新赋值,最后输出flag的值(?类)
。另一种方法就是由高级向低级的筛选,我们就叫做反向筛选法。对任一个四位数我们先判断它是不是一类,如果
是就标识为一类号码,否则继续判断是不是二类,如果是就标识为二类号码,否则继续以此类推向下判断,最后将
数字标识为它属于的类别。
  这两种筛选方法各有千秋,总体上来说正向筛选法效率较差但代码相对会简单些,就是一行一行的if语句写下
来,而反向筛选法效率较高但代码会相对复杂点,因为其中涉及到数层的if嵌套。
  另外说下筛选中的难点(正反向一样),个人认为最难的就是abcd和abc顺子的判断,但是只要你抓住了这
类号码的特点,也不是很难的事。因为无论是正顺还是反顺,几个数值间肯定是一个以1或-1为差的等差数列,
所以我们只要将后面的数值依次减上其与第一个数值a的差,然后判断生成的新数值是不是一个aaaa 或aaa就可
以了。
发表于 2012-3-28 13:03:05 | 显示全部楼层
回复 12# batman
从五至一的筛选可以用set
从一至五的筛选可以用findstr
感觉效率不会差别太大
当然没有实测也不敢确定

顺子其实也没什么难的
就目前的需要还用不到判断+1和-1
直接罗列出二/三类中所有的顺子组合
然后一次findstr即可
发表于 2012-3-28 16:46:48 | 显示全部楼层
本帖最后由 neorobin 于 2012-3-28 17:09 编辑

借鉴 batman 的差值技巧:
  1. @echo off & setlocal enabledelayedexpansion
  2. > digit.txt (for /l %%i in (10000 1 19999) do (
  3.     (set s=%%i)& set /a w=!s:~1,1!,x=!s:~2,1!,y=!s:~3,1!,z=!s:~4,1!,w-=z,x-=z,y-=z,t=5
  4.     if !s:~-4!==8888 (set "t=1"
  5.     ) else if !s:~-3!==888 (set "t=2"
  6.     ) else for %%s in (000 -3-2-1 321) do if !w!!x!!y!==%%s set "t=2"
  7.     if !t!==5 if !s:~-2!==88 (set t=3) else for %%s in (00 21 -2-1) do if !x!!y!==%%s set "t=3"
  8.     if !t!==5 for %%s in (110 -1-10 101 -10-1) do if !w!!x!!y!==%%s set "t=3"
  9.     if !t!==5 if !s:~-1!==8 (set t=4) else if !y!==0 (set t=4) else (
  10.       for %%s in (011 0-1-1) do if !w!!x!!y!==%%s set t=4)
  11.     echo !t!        !s:~-4!
  12. ) )
  13. start "" digit.txt
复制代码
差值基准字符取最后一个字符, 该字符没必要在匹配比较式中出现
0000 ~ 9999 共 10000 个序列:
1 类: 1
2 类: 32
3 类: 351
4 类: 1698
5 类: 7918
发表于 2012-3-28 18:45:39 | 显示全部楼层
rem 对x的位置严格限定后得到的结果,与楼上的不同,没仔细看谁有问题
rem class1: 1
rem class2: 26          不包含8x88 88x8 888x
rem class3: 424     不包含88xx aaax abcx以及其它x变化位置的模式
rem class4: 1700    不包含8xxx aaxx xaax以及其它xx变化位置的模式
rem class5: 7868
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-16 23:29 , Processed in 0.022689 second(s), 8 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表