Board logo

标题: [数值计算] 【练习-058】批处理找出不正确的局向 [打印本页]

作者: batman    时间: 2010-1-22 22:15     标题: 【练习-058】批处理找出不正确的局向

出题目的:
    加深大家对if多条件判断的理解
    复习补位比较法
解题要求:
    代码简洁、高效、不生成临时文件
    请管理组和技术组暂缓解答,但可跟贴提示
加分原则:
    满分15分,视情况加分以思路为重
题目如下:
    有一个文本文件a.txt(如下),每行两列,其中第二列为交换点名称,第一列为每个交换点的电话号码段(一个交换点有一个
或多个号码段)。有另一文本文件b.txt(如下),每行两列,其中第二列也为交换点名称,第一列为号码局向,局向也就是指的号码
段,其计算方法是将文本中数值后面添加0并补足7位,如72581变成7258100,721变成7210000。现要求对b.txt中所有的局向根据
a.txt进行比对判断出局向不正确的行并输出c.txt(如下)。判断举例:如721 淦田,判断7210000在a.txt哪个号码段中,并判断这个
号码段后的交换点名称是不是淦田,如是的就是正确局向,不是的就是错误局向要输出。
a.txt
  1. 7210000-7219999 古岳峰
  2. 7230000-7239999 古岳峰
  3. 7257000-7257999 淦田
  4. 7258000-7278199 淦田
  5. 7270000-7274999 砖桥
  6. 7275000-7278999 砖桥
  7. 7280000-7289999 砖桥
  8. 7295000-7299999 朱亭
  9. 7347000-7348999 朱亭
  10. 7350000-7359999 朱亭
  11. 7372000-7374999 雷打石
  12. 7375000-7379999 古岳峰
  13. 7453000-7457999 雷打石
  14. 7458000-7459999 雷打石
  15. 7473000-7473999 白关
  16. 7480000-7489999 白关
  17. 7490000-7494999 白关
  18. 7495000-7499999 仙井
  19. 7610000-7619999 县城
  20. 7620000-7629999 县城
  21. 7670000-7676999 仙井
  22. 7677000-7679999 县城
  23. 7680000-7689999 县城
  24. 7690000-7693999 仙井
  25. 7694000-7699999 县城
复制代码
b.txt
  1. 721 古岳峰
  2. 721 淦田
  3. 721 白关
  4. 721 雷打石
  5. 723 砖桥
  6. 723 古岳峰
  7. 7257 仙井
  8. 7257 淦田
  9. 7257 县城
  10. 72581 淦田
  11. 72581 砖桥
  12. 7276 砖桥
  13. 7276 朱亭
  14. 7276 雷打石
  15. 7276 县城
  16. 728 朱亭
  17. 728 白关
  18. 728 砖桥
  19. 7296 朱亭
  20. 7348 淦田
  21. 7348 砖桥
  22. 7348 朱亭
  23. 7348 仙井
  24. 7373 雷打石
  25. 7373 古岳峰
  26. 7373 县城
  27. 7373 白关
  28. 7375 古岳峰
  29. 7375 淦田
  30. 7456 雷打石
  31. 7456 白关
  32. 7456 古岳峰
  33. 7473 淦田
  34. 7473 白关
  35. 7473 仙井
  36. 748 白关
  37. 748 仙井
  38. 7496 仙井
  39. 7496 白关
  40. 7496 县城
  41. 7496 雷打石
  42. 761 仙井
  43. 761 县城
  44. 761 白关
  45. 761 朱亭
  46. 7672 县城
  47. 7672 仙井
  48. 7693 县城
  49. 7693 仙井
复制代码
c.txt
  1. 721 淦田
  2. 721 白关
  3. 721 雷打石
  4. 723 砖桥
  5. 7257 仙井
  6. 7257 县城
  7. 72581 砖桥
  8. 7276 朱亭
  9. 7276 雷打石
  10. 7276 县城
  11. 728 朱亭
  12. 728 白关
  13. 7348 淦田
  14. 7348 砖桥
  15. 7348 仙井
  16. 7373 古岳峰
  17. 7373 县城
  18. 7373 白关
  19. 7375 淦田
  20. 7456 白关
  21. 7456 古岳峰
  22. 7473 淦田
  23. 7473 仙井
  24. 748 仙井
  25. 7496 白关
  26. 7496 县城
  27. 7496 雷打石
  28. 761 仙井
  29. 761 白关
  30. 761 朱亭
  31. 7672 县城
  32. 7693 县城
复制代码

[ 本帖最后由 batman 于 2010-1-22 22:31 编辑 ]
作者: tab    时间: 2010-1-23 08:53

  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "tokens=1-3 delims=- " %%i in (a.txt) do (
  3.     for /f "tokens=1,2 delims= " %%a in (b.txt) do (
  4.         set var=%%a0000
  5.         set var=!var:~0,7!
  6.         if !var! geq %%i if !var! leq %%j if %%b neq %%k echo %%a %%b>>c.txt
  7.     )
  8. )
复制代码

作者: a590687    时间: 2010-1-23 09:37

思考良久 还是被2楼的代码所折服. 相比之下我所写的代码差距太大了.就不现丑了.实在没能想到这么快捷的对比方法. 还有 if的 连续多次使用,  学习了.

  代码答案与正确答案差别在于 见附件截图.  我也没能想通为什么只 7276这组数会重复输出.  把所有文件都对比了一下也没得出结果.  
我想输出的时候加一个重复判断应该可以了...但没想到好的方法.
继续关注~
作者: summerflower    时间: 2010-1-23 15:46

  1. @echo off
  2. setlocal
  3. setlocal enabledelayedexpansion
  4. for /f "tokens=1,2" %%a in (b.txt) do (
  5.         rem 根据局向生成完整的号码段,也就是补0补足7位
  6.         set wan=%%a
  7.         for /l %%c in (0,1,6) do (
  8.                 set stmp=%%a
  9.                 set stmp=!stmp:~%%c,1!
  10.                 if not defined stmp set wan=!wan!0
  11.         )
  12.         rem 在a.txt中查找对应的号码段的交换点是否与b.txt中一致
  13.         rem flag用来标识局向是否正确,f表示不正确,t表示正确
  14.         set flag=f
  15.         for /f "tokens=1,2" %%d in (a.txt) do (
  16.                 echo %%d | find "!wan!">nul
  17.                 if not errorlevel 1 (
  18.                         if %%e==%%b (
  19.                                 set flag=t
  20.                         )
  21.                 )
  22.         )
  23.         rem 局向不正确输出结果到c.txt
  24.         if !flag!==f echo %%a %%b>>c.txt
  25. )
  26. endlocal
复制代码
第一次使用这么多for,程序运行起来好慢,竟用了十几分钟
我的结果跟楼主不一致,比楼主多了9条记录。多出的都是在b.txt里有,而在a.txt却没有对应号码段的记录
问一下,在复合语句中,能使用goto吗?本来我想用goto优化一下程序的,但goto的表现却很怪异

[ 本帖最后由 summerflower 于 2010-1-23 16:07 编辑 ]
作者: batman    时间: 2010-1-23 21:24     标题: 回复 2楼 的帖子

这个代码出不了正确结果,因为b.txt中任一个局向不可能与a.txt每行都匹配。。。

[ 本帖最后由 batman 于 2010-1-23 22:03 编辑 ]
作者: 523066680    时间: 2010-1-23 21:35

我愣了老半天 ,终于感觉好像是地名(一直觉得像人名,动画看多了) o_O

好像是以b.txt为标准,衡量a.txt 地点的 xx编码区间是否对头

[ 本帖最后由 523066680 于 2010-1-23 21:37 编辑 ]
作者: summerflower    时间: 2010-1-24 10:46

为什么我的程序运行起来那么慢?十多分钟,这个速度也太恐怖了吧
是启用了变量延迟的原因还是find运行很慢

[ 本帖最后由 summerflower 于 2010-1-24 10:48 编辑 ]
作者: Batcher    时间: 2010-1-24 12:02     标题: 回复 7楼 的帖子

在for循环里面使用echo xxx | find xxx的是一个不太好的方案,你先试着从这里入手调优吧。

参考:提高批处理代码效率的常用技巧及方案
http://www.bathome.net/thread-4831-1-1.html
作者: wxcute    时间: 2010-1-24 21:28

一开始看实在不明白 “局向” 做何解,现在终于是懂了。
题目的通俗说法就是 “B 中地点的号码(加 0 补足位数后)是否在 A 指定的号码段中,不在则显示出来”。

[ 本帖最后由 wxcute 于 2010-1-24 21:31 编辑 ]
作者: batman    时间: 2010-1-26 14:59

给出本人的解:
  1. @echo off&setlocal enabledelayedexpansion
  2. (for /f "tokens=1,2" %%a in (b.txt) do (
  3.     set "str=%%a0000000"&set "str=!str:~,7!"&set "flag="
  4.     for /f "tokens=1-3 delims=- " %%c in (a.txt) do (
  5.         if not defined flag if !str! geq %%c if !str! leq %%d if "%%b" equ "%%e" set "flag=a"
  6.     )
  7.     if not defined flag echo %%a %%b
  8. ))>c.txt
  9. start c.txt
复制代码

作者: wxcute    时间: 2010-1-26 22:13     标题: 钻空子,省点代码^_^

  1. @echo off
  2. for /f "tokens=1*" %%b in (b.txt)do (
  3.  for /f "tokens=1-3 delims=0- " %%r in (a.txt)do (
  4.   if "%%r" leq "%%b" if "%%b" leq "%%s" if "%%c"=="%%t" set Flag=1
  5.  )
  6.  if defined Flag (set Flag=)else echo %%b %%c
  7. )
  8. pause
复制代码

作者: zqz0012005    时间: 2010-1-27 10:56     标题: 回复 3楼 的帖子

又是一个不知道怎么在CMD窗口中复制文字的。。。

建议你们先学好基础,再做这种问题,循序渐进。
作者: clamber    时间: 2010-1-27 12:14

  1. @echo off&for /f "tokens=1,2 delims= " %%i in (b.txt) do (set var=%%i0000&&call findstr /r /c:"%%var:~,7%%-....... %%j" a.txt||echo %%i %%j>>c.txt)
复制代码

作者: a590687    时间: 2010-1-28 07:30     标题: 回复 12楼 的帖子

会复制 , 但忘了复制 直接QQ截图了.   以后我想着点.




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2