[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[挑战] 批处理寻找所有条件里相同的数字

假设有如下数字:

2190717
219117
2199817
2190517
2191417
21921917

为了大量数据统计的需要,我用一句话生成类似的数据
for /l %%i in (1,1,100) do echo 219%%i17>>1.txt

在这堆数据里,都有 219 的前缀和 17 的后缀,而中间的数据是随机的。

现在,我们的题目来了:
       利用批处理,找出 219 的前缀 和  17 的后缀,并将去掉后的结果输出到2.txt

输出的结果类似:
1
2
3
……
100

      前提:219 和 17在题目中是未知的,所以我们需要找出这2个未知的数据。。(这也是这里的难点)

sort 之后,第一行与最后一行,对比分析,应该可以得到前缀吧

后缀的话,开始是想,二进制后几位也相同,用>> 移位,然后 mod 2 , 如果移位后,最后一位都是0或者1,那么MOD值也相同,如果有0有1,那么MOD值就不同,然后根据移位的位数,来分析后缀。
测试了下,咳..数字运算只能支持2^32,数字过长就没办法了..

只能当作字符串测试了,检查 %str:~-n+1,-n% 是不是相同了..效率估计不高

[ 本帖最后由 caruko 于 2009-12-8 11:41 编辑 ]

TOP

为什么我还是没看懂题目...
既然是自动截开头,,那么219开头也可以被认为21开头啊..

TOP


这个有点像在许多字符串中找到相同的字符串~
o(∩_∩)o...~~~
空间:http://hi.baidu.com/fair_jm
喜欢批处理的没事的话去逛逛哦~~

TOP

根据第一行的长度,取得动态代码行:

内容为:set  #c0!str:~0,1!=!str:~0,1!&set  #c1!str:~1,1!=!str:~1,1!  ...

%com%=从串首开始
%bom%=从串尾开始

变量定义规则:  #c+列号+字符=字符

这样会根据各列字符,动态定义变量,如果同一列有不同字符,则会定义多个变量,否则只有一个

for +set 最后判断同一列是否有二个以上变量,即可知道是否为前/后缀结束

[ 本帖最后由 netbenton 于 2009-4-22 22:43 编辑 ]

TOP

回复 26楼 的帖子

能把思路说说吗?看代码太累了!
技术问题请到论坛发帖求助!

TOP

回版主:
不好意思,偶知道怎么加code,只是回贴时,粘贴后就马上点发表了,没注意,谢谢提醒。
以后一定注意。



偶在22楼是没有表达得清楚,并且有很大错误,不好意思。

其实是想说:
方法一,sort后可以对比前后行仅仅得出前缀。后缀没有解决。(发现确实不行)
方法二,(24楼代码)则可以分别得出前、后缀,并且速度还可以。(可行,但与22楼表达的有点不同)


完整代码如下(文本文件名与批处理文件名关联了,1000行记录3秒内完成替换):

  1. @echo off
  2. set $=!
  3. setlocal enabledelayedexpansion
  4. (for /l %%i in (1,1,1000) do echo 219%%i17)>%~n0.txt
  5. set /p var=<%~n0.txt
  6. set com=
  7. set bom=
  8. for /l %%a in (0,1,32) do (
  9. set "bom=!bom!&set #b%%a!$!str:~-%%a,1!$!=!$!str:~-%%a,1!$!"
  10. if "!var:~%%a,1!"=="" goto :scok
  11. set "com=!com!&set #c%%a!$!str:~%%a,1!$!=!$!str:~%%a,1!$!"
  12. )
  13. :scok
  14. set com=!com:~1!
  15. set bom=!bom:~1!
  16. set "bom=!bom:*&=!"
  17. for /f %%i in (%~n0.txt) do (set str=%%i
  18. %com%
  19. %bom%
  20. )
  21. set var=
  22. set tou=
  23. for /f "tokens=1,2 delims==" %%a in ('set #c') do (set str=%%a
  24. if "!str:~2,1!"=="!var!" goto :oktou
  25. set tou=!tou!%%b
  26. set var=!str:~2,1!
  27. )
  28. :oktou
  29. set wei=
  30. set var=
  31. for /f "tokens=1,2 delims==" %%a in ('set #b') do (set str=%%a
  32. if "!str:~2,1!"=="!var!" goto :okwei
  33. set wei=%%b!wei!
  34. set var=!str:~2,1!
  35. )
  36. :okwei
  37. set tou=%tou:~,-1%&set wei=%wei:~1%
  38. ::前面的找前后缀,后面的进行替换
  39. (for /f %%i in (%~n0.txt) do (set str=#%%i#
  40. set str=!str:#%tou%=!
  41. echo !str:%wei%#=!
  42. ))>%~n0dest.txt
  43. start %~n0dest.txt
  44. pause
复制代码

[ 本帖最后由 netbenton 于 2009-4-22 19:03 编辑 ]

TOP

回复 24楼 的帖子

Q:所发代码不止一行时请用 code 把代码扩起来
A:如何用code把代码扩起来 ,请点我。
未细看你的代码,但若你是按22楼所说的思路来解的话,可能有考虑不周的地方。
楼主题意描述不清,我们假设所谓的 前缀和后缀 是指所有行都有的特征。
如果你sort排序后得到的第一行和最后一行分别是以下两行,能得到正确结果吗?
假设前缀为 1234
后缀为 4321
sort排序后
第一行为 1234555674321
最后一行为 12345556743214321
技术问题请到论坛发帖求助!

TOP

做出来了

  1. @echo off
  2. set $=!
  3. setlocal enabledelayedexpansion
  4. (for /l %%i in (1,1,100) do echo 219%%i17)>%~n0.txt
  5. set /p var=<%~n0.txt
  6. set com=
  7. set bom=
  8. for /l %%a in (0,1,32) do (
  9.         set "bom=!bom!&set #b%%a!$!str:~-%%a,1!$!=!$!str:~-%%a,1!$!"
  10.         if "!var:~%%a,1!"=="" goto :scok
  11.         set "com=!com!&set #c%%a!$!str:~%%a,1!$!=!$!str:~%%a,1!$!"
  12. )
  13. :scok
  14. set com=!com:~1!
  15. set bom=!bom:~1!
  16. set "bom=!bom:*&=!"
  17. for /f %%i in (%~n0.txt) do (set str=%%i
  18. %com%
  19. %bom%
  20. )
  21. set var=
  22. set tou=
  23. for /f "tokens=1,2 delims==" %%a in ('set #c') do (set str=%%a
  24.         if "!str:~2,1!"=="!var!" goto :oktou
  25.         set tou=!tou!%%b
  26.         set var=!str:~2,1!
  27. )
  28. :oktou
  29. set wei=
  30. set var=
  31. for /f "tokens=1,2 delims==" %%a in ('set #b') do (set str=%%a
  32.         if "!str:~2,1!"=="!var!" goto :okwei
  33.         set wei=%%b!wei!
  34.         set var=!str:~2,1!
  35. )
  36. :okwei
  37. echo %tou:~,-1%     %wei:~1%
  38. pause
复制代码

[ 本帖最后由 netbenton 于 2009-4-22 18:25 编辑 ]

TOP

用sort 排序一次后,只需比较第一条和最后一条记录即可得出前缀了。

=========================
set /p one=<a.txt
...测串长
for /f "delims=" %%a in (a.txt) do (set str=%%a
set f1=!str:~1,1!
set f2=!str:~2,1!
set f3=!str:~3,1!

...根据串长动态生成行数,变%var1%代替代码行
set r1=!str:~-1!
set r2=!str:~-2!
set r3=!str:~-3!

...
)

最后再与第一条记录的比较就可以得到前后缀了。

TOP

原帖由 batman 于 2008-10-17 16:56 发表
写了个删除前缀的(后缀亦然),效率不怎么高:@echo off&setlocal enabledelayedexpansion
set /p str=nul

有点问题,把生成的1.txt取反后得到的结果有BUG,对这行7171912 删前缀得到的结果是912

[ 本帖最后由 lorn1234 于 2009-1-12 00:55 编辑 ]

TOP

原帖由 flyinspace 于 2008-10-19 12:17 发表
我的思路是这样的。

假设有1000组数据。。

任意取两个数据进行比较,取相同的数据作为参考量。
假设 2910117
          2910217
这两个数据,就取到了 2910 这个参考。

然后进行一次 Findstr /r "^2910" ...



按照您这个思路,干脆叫cmd去跳楼吧。。。


这么比较,都不知要花费多少时间在这里面。。。何况比到最后,都不一定能比出个结果。。。就算有结果了。。。也不一定正确。。。

TOP

得到前辍使用sort +n来识别

sort +1 & sort +2  & sort +3

TOP

我的思路是这样的。

假设有1000组数据。。

任意取两个数据进行比较,取相同的数据作为参考量。
假设 2910117
          2910217
这两个数据,就取到了 2910 这个参考。

然后进行一次 Findstr /r "^2910" 的输出查找,看找到的数据量是否有1000条。
若不满足1000条,则取  291 查找,看是否有1000条。直到满足

或者
一个一个的向后取值
例如 findstr /r "^2"  直到不满足条件为止。。

不过,我发现你们的代码可能更适合一些了 。。

继续研究一下,看是否有BUG呢。

TOP

  1. @echo off && setlocal enabledelayedexpansion
  2. call :i l +
  3. call :i r -
  4. set /a r+=1
  5. for /f %%a in (1.txt) do set "v=%%a" && echo !v:~%l%,%r%!>>2.txt
  6. goto :eof
  7. :i
  8. set "?=%2"
  9. set "s="
  10. if "%?%"=="+" (set i=0) else (set i=-1)
  11. :repeat
  12. for /f %%a in (1.txt) do set "v=%%a" && set "s=!s!!v:~%i%,1!"
  13. set "v=!v:~%i%,1!"
  14. set "s=!s:%v%=!"
  15. if not defined s (set /a i%?%=1 && goto repeat) else (set %1=%i%)
复制代码

TOP

返回列表