Board logo

标题: [文本处理] 【已解决】BAT:如何提高多个文本数据交叉合并的运行速度 [打印本页]

作者: 思想之翼    时间: 2015-2-25 02:59     标题: 【已解决】BAT:如何提高多个文本数据交叉合并的运行速度

本帖最后由 思想之翼 于 2015-2-25 20:53 编辑
  1. @echo off
  2. for /l %%i in (1001 1 1210) do (
  3.     set s=%%i
  4.     setlocal enabledelayedexpansion
  5.     set s=!s:~1!
  6.     (for /f %%a in (!s!_1.txt) do (
  7.         for /f %%b in (!s!_2.txt) do (
  8.                             set str=%%a%%b
  9.                             set n1=&set n2=
  10.                             for %%l in (1 2 3 4 5 6 7 8 9 0) do (
  11.                                 if "!str:%%l=!" neq "!str!" (
  12.                                    set n1=!n1!%%l
  13.                                 ) else  set n2=!n2!%%l
  14.                             )
  15.                             set n=!n1!A9876543210
  16.                             if "!n:~10,1!" == "3" (
  17.                                if not defined _!n1! (
  18.                                   set _!n1!=0&echo,!n1!
  19.                                )
  20.                             ) else if "!n:~10,1!" == "7" (
  21.                                 if not defined _!n2! (
  22.                                    set _!n2!=0&echo,!n2!
  23.                                 )
  24.                             )
  25.                         )
  26.     ))>d:\数据2\!s!.txt
  27.     endlocal
  28. )
  29. pause
复制代码
上述代码,是将2个文本的数据进行交叉合并,运行速度过于缓慢,若想提速,不知道如何优化,恳望得到帮助。

2个文本的数据进行交叉合并的具体过程如下(只需要最后的结果,分步过程不需要显示):
D:/数据1/内有若干txt文本:
001_1.txt
001_2.txt
002_1.txt
002_2.txt
...
210_1.txt
210_2.txt
每个txt文本内有多行数据,行数不定,每行数据在0-9之间,个数不定,最多7位数,各数字从小到大排列(数据0永远排列在最后一位)
比如:
35790
123579
1460
2456789
34567
1270
34568
257890

先将001_1.txt与001_2.txt内的数据进行合并,过程为:
001_1.txt内第1行数据与001_2.txt内的第1、2、3、4、5...行合并
001_1.txt内第2行数据与001_2.txt内的第1、2、3、4、5...行合并
...
001_1.txt内最后一行数据与001_2.txt内的第1、2、3、4、5..行合并

合并后每行数据,排序,去除重复数字,删除少于或多于7个数字的组合,只保留7个数字的组合。
比如合并后的数据为:79015914024945,去除重复数字,得到:1245790

保留下来的多行7个数字的组合,若有重复,去除重复。比如:
1236790
1236790
3456789
3456789
去除重复数据,得到:
1236790
3456789

每行数据取反集(0-9数值之间的未出现数),并将取反集后的数据从小到大排列(数据0永远排列在最后一位)。比如:
1245790的反集是:368
3456789的反集是:120

将这些数据竖排,写入D:/数据2/内的文本,文本名称为001.txt


以上是001_1.txt与001_2.txt的合并。之后,
将002_1.txt与002_2.txt合并,得到的数据,竖排,写入D:/数据2/内,文本名称为002.txt
将003_1.txt与003_2.txt合并,得到的数据,竖排,写入D:/数据2/内,文本名称为003.txt
...
将210_1.txt与210_2.txt合并,得到的数据,竖排,写入D:/数据2/内,文本名称为210.txt
作者: caruko    时间: 2015-2-25 12:16

快不了,你计算一下**生了多少条数据?
必须循环那么多次数。
作者: apang    时间: 2015-2-25 13:13

合并后每行数据,排序,去除重复数字,删除少于或多于7个数字的组合,只保留7个数字的组合。
比如合并后的数据为:79015914024945,去除重复数字,得到:1245790

为什么一定要这一步呢?直接取反集(79015914024945反集为368),然后找出不重复的3位数,有什么区别吗?
作者: apang    时间: 2015-2-25 13:17

本帖最后由 apang 于 2015-2-26 15:54 编辑
  1. Dim srcDir, dstDir, fso
  2. srcDir = "D:\数据1"
  3. dstDir = "D:\数据2"
  4. Set fso = CreateObject("Scripting.FileSystemObject")
  5. If Not fso.FolderExists(dstDir) Then fso.CreateFolder(dstDir)
  6. Dim i, f1, f2, f, objFile1, objFile2, s1, s2
  7. For i = 1001 to 1210
  8.         f1 = srcDir & "\" & Mid(i, 2) & "_1.txt"
  9.         f2 = srcDir & "\" & Mid(i, 2) & "_2.txt"
  10.         If fso.FileExists(f1) and fso.FileExists(f2) Then
  11.                 f = dstDir & "\" & Mid(i, 2) & ".txt"
  12.                 Set objFile1 = fso.OpenTextFile(f1, 1)
  13.                 Set objFile2 = fso.OpenTextFile(f2, 1)
  14.                 s1 = RegEx(objFile1.ReadAll)
  15.                 s2 = RegEx(objFile2.ReadAll)
  16.                 objFile1.Close
  17.                 objFile2.Close
  18.                 fso.OpenTextFile(f, 2, true).Write CombineNum(s1, s2)
  19.         End If
  20. Next
  21. MsgBox "OK"
  22. ''删除空白行
  23. Function RegEx(txt)
  24.         Dim re
  25.         Set re = New RegExp
  26.         re.Pattern = "^(\s*\n)+"
  27.         txt = re.Replace(txt, "")
  28.         re.Pattern = "(\s*\n)+"
  29.         re.Global = true
  30.         RegEx = re.Replace(txt & vbLf, vbLf)
  31. End Function
  32. ''合并数据
  33. Function CombineNum(ByVal s1, ByVal s2)
  34.         Dim ar1, ar2, j, k, n, s, m, str
  35.         ar1 = Split(s1, vbLf)
  36.         ar2 = Split(s2, vbLf)
  37.         For j = 0 to UBound(ar1) - 1
  38.                 For k = 0 to UBound(ar2) - 1
  39.                         s = ""
  40.                         For n = 1 to 10
  41.                                 m = n Mod 10
  42.                                 If InStr(ar1(j) & ar2(k), m)=0 Then s = s & m
  43.                         Next
  44.                         If Len(s) = 3 and InStr(str, s) = 0 Then
  45.                                 str = str & s & vbCrLf
  46.                         End If
  47.                 Next
  48.         Next
  49.         CombineNum = str
  50. End Function
复制代码

作者: 思想之翼    时间: 2015-2-25 20:49

回复 4# apang

是我弄错了,代码运行速度快了不少。谢谢!!!




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