手把手教你TestComplete_文件比对算法讨论

 

 

 

文件比对是一个非常古老的话题,但是真要做好并不容易。

 

来看看下面两个文件:

FILE1:

A

B

D

E

F

FILE2:

 

B

C

D

E

G

 

 

首先琢磨一下,影响效率的因素:

1.  读文件,硬盘IO读写肯定是很花时间的,两种读法,一种是一次全部读入,比较占内存,另一种是边做边读,省内存,写起来麻烦一些,花时间;

2.  字符串比对,尤其长字符串,比对次数当然少一些最好;

3.  数据结构的选定

 

 

分析:

1.  我的程序文件没有超过100m的,可以一次性读入数组来操作,内存也还能吃得消;

2.  字符串还比较长,对于比对次数要小心谨慎,别瞎浪费时间;

 

 

算法一:

1.  读出两个文件的内容,放进两个listA和listB;

2.  二次循环比对,相等的元素放入listC同时删除掉listA和listB中的该元素:listC.add(item1);listA.delete(item1);listB.delete(item1)

3.  最后得到的结果就是A=B:listC;A-B=listA;B-A=listB,这里A-B的意思就是A文件中有但是B文件中找不到的元素

 

 

琢磨:首先list的效率本身就不怎么地,其次还频繁的delete和add,效率一般,不过算法够简单。

 

 

算法二:

1.  读出两个文件的内容,放进两个arrA和arrB;

2.  二次循环比对,相等的元素放入arrC,每次增加前都redim一次arrC,同时删除掉arrA和arrB中的该元素,又不是list,怎么删除呀,呃。。。那就把那个元素值改成某个确定不会出现在元素集合中的某个值。这招够馊的!不过不用重新整理数组,应该速度会快点

3.  最后得到的结果就是A=B:arrC;A-B=arrA去掉特定修改元素;B-A=arrB去掉特定修改元素,这里A-B的意思就是A文件中有但是B文件中找不到的元素

 

评价:

1.数组操作会快些,缺点是每次都redim重新分配内存,过于频繁,影响效率;

2.不过没重新整理数组这个不错;

3.比对了很多已经排除的元素,浪费了

 

 

看完了上面两个算法,都有比较明显的问题,能不能别重复比对元素,并且别在比对过程中不断重新分配内存的方法,大家来看看下面这个算法:

 

1.  读出两个文件的内容,放进两个arrA和arrB;

2.  二次循环开始比对,遇到相等的元素,arrA(i)和arrA(arrA起始下标+匹配上的元素-1)交换,arrB(j)和arrB(arrA起始下标+匹配上的元素-1)交换,这样不断的冒泡,arrA和arrB的前面就是匹配上的元素,后面就是各自独有的元素;

3.  最后得到的结果就是A=B:arrA(0, 匹配上的元素-1)=arrB(0,匹配上的元素-1);A-B=arrA(匹配上的元素,arrA的整个个数);B-A= arrB(匹配上的元素,arrB的整个个数),这里A-B的意思就是A文件中有但是B文件中找不到的元素

 

 

这个可能大家看得有点点晕忽,画个图吧:

 

 

 

 

 

大家看明白了吧,这个算法的优点是:

 

1.  不用比对过程中使用新的数据结构来不断分配内存空间;

2.  每次比对都是过滤后的元素比对,比对次数从笛卡儿乘积变成了阶乘;

3.  如果两个文件经过排序的,基本上就是arrA和arrB中用来做主比对数组的元素个数了,说到这里,大家一琢磨,就会发现,如果arrA和arrB大小不同,元素少的那个数组放第一层循环,会少循环几次,次数就是arrA和arrB元素的差值。

 

 

好吧,附带上代码给大家做个参考:

 

 

 

 

'比对两个文本文件,返回是否相等

'比对结果写入日志

'注意:比对的文件最后不要有空行

 

Function FblnCmpFile(strFile1,strFile2,strLog)

 

dim intlb1,intlb2,intub1,intub2,intfind

dim blnFind

dim strS1,strRes

dim sFileCont

dim i,j

 

'1.将strFile1和strFile2分别读入arr1和arr2

    

  if not FblnFileExist(strFile1) then

                   Log.Warning(strFile1 & " 不存在")

    FblnCmpFile=False

    exit Function

  End If

 

  if not FblnFileExist(strFile2) then

                   Log.Warning(strFile2 & " 不存在")

    FblnCmpFile=False

    exit Function

  End If

   

  sFileCont=aqFile.ReadWholeTextFile(strFile1,aqFile.ctUnicode)

  arr1=split(sFileCont,vbcrlf)

'Log.Message("文件1:" & sFileCont)

'for i=0 to ubound(arr1)

'  Log.Message(arr1(i))

'Next

 

  sFileCont=aqFile.ReadWholeTextFile(strFile2,aqFile.ctUnicode)

  arr2=split(sFileCont,vbcrlf)

'Log.Message("文件2:" & sFileCont)

'for i=0 to ubound(arr2)

'  Log.Message(arr2(i))

'Next

 

'2. 对两个数组进行比对

 

intlb1=lbound(arr1)

intlb2=lbound(arr2)

intub1=ubound(arr1)

intub2=ubound(arr2)

intfind=0

 

for i=intlb1 to intub1

  blnFind=false

  for j=intlb2+intfind to intub2

    Log.Message(arr1(i) & vbcrlf & arr2(j))

    if arr1(i)=arr2(j) then

      intfind=intfind+1

Log.Message("swtich arr2:" & arr2(intlb2+intfind-1) & "和" & arr2(j))

      strS1=arr2(intlb2+intfind-1)

      arr2(intlb2+intfind-1)=arr2(j)

      arr2(j)=strS1

 

      blnFind=true

      exit for

    end if

  next

  if blnFind=true then

Log.Message("swtich arr1:" & arr1(intlb1+intfind-1) & "和" & arr1(i)) 

    strS1=arr1(intlb1+intfind-1)

    arr1(intlb1+intfind-1)=arr1(i)

    arr1(i)=strS1

   

    blnFind=false

  end if

next 

 

Log.Message("处理完成") 

for i=0 to intub1

  Log.Message(arr1(i))

Next

 

for i=0 to intub2

  Log.Message(arr2(i))

Next

 

 

'3.写日志

'A=B:arr1(intub1-intfind,intub1)

'A-B:arr1(0,intub1-intfind-1)

'B-A:arr2(0,intub2-intfind-1)

 

sFileCont="比对文件: " & vbcrlf & "[" & strFile1 & "] 和 [" & strFile2 & "]" & vbcrlf & vbcrlf

sFileCont=sFileCont & "比对结果为:" & vbcrlf

sFileCont=sFileCont & "A 共有记录: " & intub1+1 & "条" & vbcrlf

sFileCont=sFileCont & "B 共有记录: " & intub2+1 & "条" & vbcrlf

sFileCont=sFileCont & "找到AB相同记录: " & intfind & "条" & vbcrlf 

 

if intfind=intub1+1 and intfind=intub2+1 Then

  sFileCont=sFileCont & vbcrlf & "两个文件完全相等" & vbcrlf

  FblnCmpFile=True

Else

  sFileCont=sFileCont & vbcrlf & "两个文件不相等" & vbcrlf

 

  'A=B

  strRes=""

  for i=intlb1 to intlb1+intFind-1

    strRes=strRes & arr1(i) & vbCrLf

  next

 

  sFileCont=sFileCont & vbcrlf & "A=B: " & vbcrlf & strRes & vbcrlf

 

  'A-B

  strRes=""

  for i=intlb1+intFind to intub1

    strRes=strRes & arr1(i)& vbCrLf  

  next

  

  sFileCont=sFileCont & vbcrlf & "A-B: " & vbcrlf & strRes & vbcrlf

 

  'B-A

  strRes=""

  for i=intlb2+intFind to intub2   

    strRes=strRes & arr2(i)& vbCrLf

  next 

  sFileCont=sFileCont & vbcrlf & "B-A: " & vbcrlf & strRes & vbcrlf

  FblnCmpFile=False

end if

 

call aqFile.WriteToTextFile(strLog,sFileCont,aqFile.ctUnicode,True)

 

End Function

 

 

 

 

使用方法:

 

strFile1=Project.Path & "data\file1.tmp.txt"

strFile2=Project.Path & "data\file2.tmp.txt"

strLog=Project.Path & "data\fcmp.log"

 

call FblnCmpFile(strFile1,strFile2,strLog)

 

 

 

 

God bless u!

 

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Testingba

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值