回 帖 发 新 帖 刷新版面

主题:如何做文本内容比较?

如何做文本内容比较?
有2个文本框text1和text2,要求后期输入内容,例如在text1中输入20个名字,在text2中输入5个名字,而且是每个姓名占据一行,然后通过按钮确认进行比较(逐行名字比较),如果text2中的名字在text1中出现,则该名字输出到text3中;如果text2中的名字不在text1中出现,则该名字输出到text4中!
本人做了一个代码,如果进行4000人以上的对比,就会出现停顿,请问如何提高工作效率,并且能在短时间内完成工作?以下是本人的代码,请大侠们给小弟指教一下!

Private Sub Command1_Click()
   For i = 0 To UBound(Split(Text1.Text, vbCrLf))
        cz = 0
        For j = 0 To UBound(Split(Text2.Text, vbCrLf))
            If Split(Text1.Text, vbCrLf)(i) = Split(Text2.Text, vbCrLf)(j) Then
                cz = 1
            End If
        Next
        If cz = 1 Then
            If Split(Text1.Text, vbCrLf)(i) <> "" Then
                Text3.Text = Text3.Text & Split(Text1.Text, vbCrLf)(i) & vbCrLf
            End If
        End If
        If cz = 0 Then
            If Split(Text1.Text, vbCrLf)(i) <> "" Then
                Text4.Text = Text4.Text & Split(Text1.Text, vbCrLf)(i) & vbCrLf
            End If
        End If
Next

End Sub

回复列表 (共5个回复)

沙发

Split(Text1.Text, vbCrLf)的反复引用,应是导致速度变换的一个原因
解决之道,设置两个数组。一个是总集合,一个是子集。
然后
for i=0 to ubound(总集合)
    已找到=f***'忘记了拼写
    for j=0 to ubound(子集)
        if 总集合(i)=子集(j) then
           已找到=ture
           text3=text3 & 子集(j) & vbcrlf
           exit for
        endif
     next j
     if not 已找到 then text4=text4 & 子集(j) & vbcrlf
next i
这个算法似乎有些慢。可以使用别的算法例如“正交法”(我只听过,不会用),还可以使用交集运算等等

板凳

要想速度快,不能用字符查询法,而必须采用ASCII码查询,也就是说,把text1和text2的内容都转换为ASCII码,装入整形数组,再在数组中查询

3 楼

楼主怎么不提供一下测试数据让大家测试一下?

下面的代码没用到什么高级的技巧,仅仅是使用缓存,我比较了一下12000*12000的样本,2秒内搞定。当然,我的测试样本是直接google回来的人名大全,也许测试不科学,但这个算法与测试样本相等与否无关,因此这个因素不会影响最终速度。

[code=c]
Private Sub Command1_Click()
    Text3.Text = ""
    Text4.Text = ""
    
    '需要比较的两组文本及它们的上界
    Dim a() As String, b() As String
    Dim al As Long, bl As Long
    a = Split(Text1.Text, vbNewLine)
    b = Split(Text2.Text, vbNewLine)
    al = UBound(a)
    bl = UBound(b)
    
    '保证小数组在前
    If al = -1 Or bl = -1 Then Exit Sub
    If al > bl Then
        Dim tmp() As String
        Dim tmpl As Long
        
        tmp = a
        a = b
        b = tmp
        
        tmpl = al
        al = bl
        bl = tmpl
    End If
    
    '按大数组长度声明两个数组用来保存结果,并记录其实际长度
    Dim c() As String, d() As String
    Dim cl As Long, dl As Long
    ReDim c(bl), d(bl)
    cl = 0
    dl = 0
    
    '循环比较
    Dim i As Long, j As Long
    For i = 0 To al
    
        Dim item As String
        item = a(i)
    
        Dim contain As Boolean
        contain = False
        For j = 0 To bl
            If item = b(j) Then
                contain = True
                Exit For
            End If
        Next
        
        '保存结果
        If contain Then
            c(cl) = item
            cl = cl + 1
        Else
            d(dl) = item
            dl = dl + 1
        End If
        
    Next
    
    '去掉多余的元素,拼接成字符串显示
    If cl > 0 Then
        ReDim Preserve c(cl - 1)
        Text3.Text = Join(c, vbNewLine)
    End If
    
    If dl > 0 Then
        ReDim Preserve d(dl - 1)
        Text4.Text = Join(d, vbNewLine)
    End If
End Sub
[/code]

4 楼


楼上的代码小弟测试用过了,真的2秒成功了,还真是谢老大了

5 楼


我来回复

您尚未登录,请登录后再回复。点此登录或注册