替换字符串中的关键字,速度非常慢.有什么好办法??

时间:2022-03-17 14:44:52
strcontent为长字符串.

F = FreeFile
Open app.path & "\mystr.ini" For Input As #F
Do Until EOF(F)
Line Input #F, str

''将str替换成空
if instr(strcontent,str)>0 then
  strcontent=replace(strcontent,str,"")
end if

''其他字符与str组合,再过滤
strtemp= "AA" & str
if instr(strcontent,strtemp)>0 then
  strcontent=replace(strcontent,strtemp,"")
end if

strtemp= str & "BB" 
if instr(strcontent,strtemp)>0 then
  strcontent=replace(strcontent,strtemp,"")
end if

strtemp= str & "CC" & "899"
if instr(strcontent,strtemp)>0 then
  strcontent=replace(strcontent,strtemp,"")
end if

......
......
......
......
......
......组合过滤比较多

loop

在mystr.ini里,每行是一个关键字,大概有6000行.全部循环完,感觉非常慢.请问有什么好一点办法嘛???

71 个解决方案

#1


错误更改,,LOOP下面少了一行..
Close #F

#2


组合过滤比较多的话是不是可以组合下

不过不知道这样的效率有没有提高

至少代码少了的

#3


你看看逻辑
if instr(strcontent,str)>0 then
  strcontent=replace(strcontent,str,"") 
你在这里已经把str替代结束了,怎么能找到"AA" & str的字符串呢?你后面那些能找到么?
end if

''其他字符与str组合,再过滤
strtemp= "AA" & str
if instr(strcontent,strtemp)>0 then
  strcontent=replace(strcontent,strtemp,"")
end if

也许我分析错了,你再看看

实在不行就给客户一个进度条

#4


不要判断,直接调用 replace

#5


你替换的规则是怎么样?
是在mystr.ini中的任一行数据str,
把这三种组合"AA" & str,str & "BB" 和str & "CC899"的字符串
都替换为""吗?

#6


是这样,strcontent里面,不一定有这个关键字组合,所以需要判断一下,有这个关键字组合则过滤掉..即,if instr(strcontent,strtemp)>0 then end..

这6000多个关键字,在一个strcontent里,有可能没有一条符合条件,有可能有多条符合条件..但却需要全部判断,过滤一遍.

#7


TO:clear_zero(clear_zero) 
谢谢你的意见,我说的是有问题..

这个判断应该放到最后,前面应该放str & "BB" 等等组合的关键字过滤...
if instr(strcontent,str)>0 then
  strcontent=replace(strcontent,str,"")
end if

#8


TO:cangwu_lee(橙子)
直接替换会快嘛,,谢谢,,我试一下.

#9


For VB5 user:
Public Sub ReplaceAll(ByRef sOrigStr As String,  _
            ByVal sFindStr As String, _
            ByVal sReplaceWithStr As String, _
            Optional bWholeWordsOnly As Boolean)
'
' Replaces all occurances of sFindStr with sReplaceWithStr
'
    Dim lPos As Long
    Dim lPos2 As Long
    Dim sTmpStr As String
    Dim bReplaceIt As Boolean
    Dim lFindStr As Long


    On Error GoTo vbErrorHandler

    lFindStr = Len(sFindStr)

    lPos2 = 1
    bReplaceIt = True
    sTmpStr = sOrigStr

    Do
        lPos = InStr(lPos2, sOrigStr, sFindStr)
        If lPos = 0 Then
            Exit Do
        End If
        If bWholeWordsOnly Then
            On Error Resume Next
            If lPos = 1 Or (Mid$(sOrigStr, lPos - 1, 1) = " ") Then
                If (Mid$(sOrigStr, lPos + lFindStr, 1) = " ") Or Mid$(sOrigStr, lPos + lFindStr + 1, 1) = "" Then
                    bReplaceIt = True
                Else
                    bReplaceIt = False
                End If
            End If
        End If
        If bReplaceIt Then
            If lPos > 1 Then
                sTmpStr = Left$(sOrigStr, lPos - 1)
            Else
                sTmpStr = ""
            End If
            sTmpStr = sTmpStr & sReplaceWithStr
            sTmpStr = sTmpStr & Mid$(sOrigStr, lPos + lFindStr, Len(sOrigStr) - (lPos + lFindStr - 1))
            sOrigStr = sTmpStr
        End If
        lPos2 = lPos + 1
    Loop
    sOrigStr = sTmpStr
    Exit Sub

vbErrorHandler:
    Err.Raise Err.Number, "StrHandler ReplaceAll", Err.Description


End Sub

#10


TO:junki(『.NET技术争霸天下』) 
你好,我说的意思是,有N多种组合,如果符合条件就要过滤掉,一条长字符串中,有可能一条也没有符合的组合关键字.但是6000多条str也要全运行一圈

#11


不要判断,直接调用 replace

#12


这种问题想快都难。

6000条内容,再加上N种组合,6000*N 次循环,还是处理VB不善长的大字符串处理,加进度条吧!

另外,少一个 instr() 判断应该会快许多。

#13


不知道楼主什么意图,在测试VB的效率?

如果是真想实用,单看楼主写的那些,简直是天方夜谭,程序绝对没这么写的.

#14


replace函数

#15


楼主考虑一下正则表达式

--------
www.vicmiao.com
努力就有美好时光!

#16


vb里不可以用正则么?

#17


正则表达式

#18


可以将文件读入一个字符串变量,然后再对该字符串变量进行replace操作,如果应用中需要每一行的数据,再用split函数分解。这样避免在循环中频繁调用replace函数,replace函数可以将字符串中所有要替换的内容一次性完成。
希望这个思路与你的应用不冲突!

#19


这样:
每读出一句的判断还是要的。因为你的所有组合,都是包含 str 的,因此若长字符串不包含 str ,其他的所有操作都可以省掉,直接处理下一句。

F = FreeFile
Open app.path & "\mystr.ini" For Input As #F
Do Until EOF(F)
Line Input #F, str

if instr(strcontent,str) then
  strcontent=replace(strcontent,"AA" & str,"")
  strcontent=replace(strcontent,str & "BB","")
  strcontent=replace(strcontent,str & "CC" & "899","")
  strcontent=replace(strcontent,str,"")
end if

loop
Close #F

#20


AA,BB.....这些处理一次就行了吧?为什么要放在每一个line中?

#21


AA,BB这些也是变量?

#22


vb 中可以用正则,不过这个是字符替换,与正则不相干吧?

#23


AA,BB.....这些处理一次就行了吧?为什么要放在每一个line中?
-------------------------
哦,是我糊涂了 !

#24


TO:VBAdvisor(Sunlight):
这个函数不错,但过滤的关键字组合太多,也是同样的问题,反应慢.

#25


TO:theforever(碧海情天)
呵呵,不是测CPU呀..不是没事干..

#26


我知道我的方法的确不可取,效率低下...所以请大家支招..

#27


都成头条了!

#28


直接用REPLACE替换,,效率差不多,慢呢.

#29


TO:fxy_2002(阿勇)
这种问题想快都难。
6000条内容,再加上N种组合,6000*N 次循环,还是处理VB不善长的大字符串处理,加进度条吧!
另外,少一个 instr() 判断应该会快许多

-------------------------
是呀,现在希望以最快的速度处理完这个长字符串,把里面不需要的过滤掉.加进度条没意义了.
因为内容里的关键字未知,所以必须得把关键字组合起来全部循环一圈..

#30


呵呵,感谢大家的关注..60太少了
我决定,如果有好的解决办法,我会另开贴
提供最好的解决办法的GG,MM,将直接得到100分..跟贴者有分..

#31


不可能有大幅度的改进。字符串处理本身就很慢。再就上要对一个长字符串反复处理。

能否说说你要干什么?看看能否采用其他方案。

#32


想不通为什么楼主要一行一行的读文件,慢的不是处理字符串,而是循环读文件。

    Dim i       As Integer
    Dim v()     As Byte
    Dim s       As String
    
    i = FreeFile()
    
    Open App.Path & "\mystr.ini" For Binary As i
        ReDim v(LOF(i) - 1)
        Get i, , v()
    Close i
    
    s = StrConv(v, vbUnicode)
    
    s = Replace(s, "AA", "")
    s = Replace(s, "BB", "")
    s = Replace(s, "CC899", "")
    ' ...

你用这种方式来看看速度如何。

#33


谁让你不用VC写...

#34


VC也差不多,关键是要用什么方法来写

#35


呵呵,有些同学看代码不仔细啊!
楼主的目的显然不是要处理 mystr.ini 这个文件,而是要使用它里面内容作为的配对条件。所以一次性读取文件和一行行读取差距不会太明显。

of123 的方法是可以改进不少的,因为 str 如果不存在,其它的配对就不会存在。加一个判断后能大幅减速少判断次数!!

加进度条不会增加处理速度,但能使界面友好,感觉就会“快”一些。关键字数量未知很容易解决,先计算出 ini 文件的行数就可以了。

#36


接着fj182(阿花) 的写下去
dim b() as string
dim i as long
dim u as long
b=split(s,vbcrlf)
u=ubound(b)
for i=0 to u
 strcontent=b(i)
  
next i
用这方法得到的strcontent和楼主在do循环中的strcontent有什么区别?
正如楼上所说,楼主不是要处理mystr.ini文件,但是,首先,用fj182(阿花) 的方式与每行读取的方式与逐行读文件的方式速度不在一个数量级,其二,避免了在循环中用replace,这肯定可以加快处理速度的,即使后面再用循环取strcontent,也只是相当于楼主的do循环次数,但少了replace操作。

#37


改正:
正如楼上所说,楼主不是要处理mystr.ini文件,但是,首先,用fj182(阿花) 的方式与逐行读文件的方式速度不在一个数量级,其二,避免了在循环中用replace,这肯定可以加快处理速度的,即使后面再用循环取strcontent,也只是相当于楼主的do循环次数,但少了replace操作。

#38


不知道楼主的主要目的是什么,按照楼主的想法,首先去掉"AA" & str,再str & "BB",但是如果有这样的情况,即"A" & str & "BB""A" & str,如果先找"AA" & str则找不到,再找str & "BB",找到并置空,而这个时候"AA" & str却出现了。这样楼主的程序就会出现问题。因此每一行只有在所有的关键字都找不到的情况才能认为ok了,这样无疑更加大了计算量。所以我觉得楼主还是应该把真正的相关需求说出来,看看有没有其他比较好的方法把问题绕过去,否则就是钻入死胡同了。

#39


我再说一下我的目的:
比如:
我一天中,要处理几万条内容
在mystr.ini里面,汇集了部分需要过滤的关键字,这是在以前的内容里找出来的
每行是一个关键字,如,第一行是北京,第二行是上海,第三行是天津....

IF内容里,有与mystr.ini里的关键字相匹配的字符串,THEN就要过滤掉
IF内容里,没有与mystr.ini里的关键字相匹配的,THEN判断,不用过滤.

如果想知道每条内容里,有没需要过滤的字符串,那么就得与mystr.ini里的全部关键字符串进行判断,全部循环一遍.
循环每个关键字时,还要加其他的组合,进行判断,过滤.

代码如下:大家看仔细了..

处理其中的一条内容
mystr.ini里面是关键字,每行一个关键字
strcontent=此内容长字符串.
str=关键字

  F = FreeFile
  Open app.path & "\mystr.ini" For Input As #F
    Do Until EOF(F)
      Line Input #F, str

      ''其他字符与str组合,再过滤

      ''组合过滤1
      strtemp= "AA" & str
      if instr(strcontent,strtemp)>0 then
        strcontent=replace(strcontent,strtemp,"")
      end if

      ''组合过滤2
      strtemp= str & "BB" 
      if instr(strcontent,strtemp)>0 then
        strcontent=replace(strcontent,strtemp,"")
      end if

      ''组合过滤3
      strtemp= str & "CC" & "899"
      if instr(strcontent,strtemp)>0 then
        strcontent=replace(strcontent,strtemp,"")
      end if

      ''组合过滤N

      ''组合过滤N+1
      ......
      ......
      ......
      ......
      ......组合过滤比较多

      ''直接将str替换成空
      if instr(strcontent,str)>0 then
        strcontent=replace(strcontent,str,"")
      end if

    Loop

  Close #F

在mystr.ini里,每行是一个关键字,大概有6000行.全部循环完,感觉非常慢.请问有什么好一点办法嘛???

再说说加组合的目的:
比如关键字='北京'时,内容里有可能存在'AA北京'或者'北京BB',这时需要替换为空.
因为关键字的不确定性,所以加了IF ... THEN 判断,再使用REPLACE替换.



#40


大家不要再考虑此代码的逻辑问题
还有'AA','BB'的前后顺序问题.

此代码只是想表达我的意图.

我有过的想法:
1.如果循环到符合条件的关键字,替换为空,然后跳出DO循环,继续下一条内容
因为每条内容里最多有一次符合条件的关键字或者组合
但是,在内容里如果没有符合的,str肯定还是要全部循环全.
其实大部分内容还是不需要过滤的.

2.将str关键字存到数组里,循环,判断,感觉还是慢

2.大家用过哈希表嘛.

#41


需要关注的:

hn123(苗濤[www.vicmiao.com]) :
楼主考虑一下正则表达式

--------
www.vicmiao.com
努力就有美好时光!
-----------------------------------------------------------------------
VBToy(无证编程):
可以将文件读入一个字符串变量,然后再对该字符串变量进行replace操作,如果应用中需

要每一行的数据,再用split函数分解。这样避免在循环中频繁调用replace函数,replace

函数可以将字符串中所有要替换的内容一次性完成。
希望这个思路与你的应用不冲突!

-----------------------------------------------------------------------
of123() :
这样:
每读出一句的判断还是要的。因为你的所有组合,都是包含 str 的,因此若长字符串不包

含 str ,其他的所有操作都可以省掉,直接处理下一句。

F = FreeFile
Open app.path & "\mystr.ini" For Input As #F
Do Until EOF(F)
Line Input #F, str

if instr(strcontent,str) then
  strcontent=replace(strcontent,"AA" & str,"")
  strcontent=replace(strcontent,str & "BB","")
  strcontent=replace(strcontent,str & "CC" & "899","")
  strcontent=replace(strcontent,str,"")
end if

loop
Close #F

-----------------------------------------------------------------------
fj182(阿花):
想不通为什么楼主要一行一行的读文件,慢的不是处理字符串,而是循环读文件。

    Dim i       As Integer
    Dim v()     As Byte
    Dim s       As String
    
    i = FreeFile()
    
    Open App.Path & "\mystr.ini" For Binary As i
        ReDim v(LOF(i) - 1)
        Get i, , v()
    Close i
    
    s = StrConv(v, vbUnicode)
    
    s = Replace(s, "AA", "")
    s = Replace(s, "BB", "")
    s = Replace(s, "CC899", "")
    ' ...

你用这种方式来看看速度如何。

-----------------------------------------------------------------------
fxy_2002(阿勇):
呵呵,有些同学看代码不仔细啊!
楼主的目的显然不是要处理 mystr.ini 这个文件,而是要使用它里面内容作为的配对条件

。所以一次性读取文件和一行行读取差距不会太明显。

of123 的方法是可以改进不少的,因为 str 如果不存在,其它的配对就不会存在。加一个

判断后能大幅减速少判断次数!!

加进度条不会增加处理速度,但能使界面友好,感觉就会“快”一些。关键字数量未知很容

易解决,先计算出 ini 文件的行数就可以了。
-----------------------------------------------------------------------
VBToy(无证编程):
接着fj182(阿花) 的写下去
dim b() as string
dim i as long
dim u as long
b=split(s,vbcrlf)
u=ubound(b)
for i=0 to u
 strcontent=b(i)
  
next i
用这方法得到的strcontent和楼主在do循环中的strcontent有什么区别?
正如楼上所说,楼主不是要处理mystr.ini文件,但是,首先,用fj182(阿花) 的方式与逐

行读文件的方式速度不在一个数量级,其二,避免了在循环中用replace,这肯定可以加快

处理速度的,即使后面再用循环取strcontent,也只是相当于楼主的do循环次数,但少了

replace操作。

-----------------------------------------------------------------------
VBAdvisor(Sunlight):
For VB5 user:
Public Sub ReplaceAll(ByRef sOrigStr As String,  _
            ByVal sFindStr As String, _
            ByVal sReplaceWithStr As String, _
            Optional bWholeWordsOnly As Boolean)

#42


如果想提速,就只能在VB的内置函数上下功夫了。这个6000*N的LOOP再减,也还是很大的。
重写一下INSTR函数,我记得网上有人贴过这个算法,速度会提高很多。

#43


看一下如下例子体会一下replace一次进行多次替换的效果:
Dim s As String
s = "adfasfsffsfsaf"
Debug.Print Replace(s, "a", "X")
相信上述例子中的替换速度比用下面的速度快
for i=1 to len(s)
   t=mid(s,i,1)
   t=replace(t,"a","X")
   newStr=newStr & t
next i

实际上就替换操作来说,本来只用调用N次的,但在楼主的思路中可能要调用6000*N次。这就像登山,有索道直接上山顶,但如果要绕着上去,无论是走路还是开车,也快不了的。

#44


我搞不懂楼主的逻辑关系。
1、将str替换成空
2、其他字符与str组合,再过滤
这第一步已经把str消灭了,后面的组合就不存在了。
strtemp= "AA" & str 
等于是 strtemp= "AA" & "" 
等于是 strtemp= "AA"
楼主可能是要先消灭组合的,最后消灭str。如果是这样,又有一个麻烦,"AA" & str & "BB",怎么考虑?

#45


1、其实慢的不是比较的速度,而是字符串被改变重新分配内存的速度。因此建议楼主使用定长字符串,足够空间的定长字符串,这肯定会提高速度。象strcontent就可以声明为全局的,减少临时字符串的使用。
2、再就是尽力不使用会产生临时字符串的函数。比如类似strcontent = replace()。可以使用Instr函数替代,找到位置后用自己的replace函数。自己的replace函数使用copymemory,速度是很快的。总之就是减少内存分配的次数。
3、另外还有一个办法就是优化关键字数据结构。这个方法很多的,比如树状结构。

#46


YaDa() 看错了吧,呵呵。
和我先前一样,以为这样只要处理一次AA、BB之类的就可以了。不过看到下面发现是先处理str和AA。BB之类的组合,最后再过虑掉str

#47


Split之后再进行Join

#48


回vbman2003(家人): 
看倒是没看错,只不过后来他改进了。
同意VBToy(无证编程):
“本来只用调用N次的,但在楼主的思路中可能要调用6000*N次”
Replace是很快的,我试过:200多K的文本,调用80次,替换了几千个数据,毒龙850CPU,一秒之内完成。

#49


LZ 请把你的源代码,和 INI 文件发送到 fengming@263.net

#50



TO fj182(阿花) ,VBToy(无证编程):

你们下面的代码,,运行到了最后,还是要想法替换的呀.我也试过,用的是数组,速度还是慢..

------------------------------------------------
    Dim i       As Integer
    Dim v()     As Byte
    Dim s       As String
    
    i = FreeFile()
    
    Open App.Path & "\mystr.ini" For Binary As i
        ReDim v(LOF(i) - 1)
        Get i, , v()
    Close i    
    s = StrConv(v, vbUnicode)

    Dim b() As String
    Dim ii As Long
    Dim u As Long
    b = Split(s, vbCrLf)
    u = UBound(b)
    For ii = 0 To u
        strcontent = b(ii)
        '''这里要进行组合,过滤,替换
        .................
        .................
    Next ii

#1


错误更改,,LOOP下面少了一行..
Close #F

#2


组合过滤比较多的话是不是可以组合下

不过不知道这样的效率有没有提高

至少代码少了的

#3


你看看逻辑
if instr(strcontent,str)>0 then
  strcontent=replace(strcontent,str,"") 
你在这里已经把str替代结束了,怎么能找到"AA" & str的字符串呢?你后面那些能找到么?
end if

''其他字符与str组合,再过滤
strtemp= "AA" & str
if instr(strcontent,strtemp)>0 then
  strcontent=replace(strcontent,strtemp,"")
end if

也许我分析错了,你再看看

实在不行就给客户一个进度条

#4


不要判断,直接调用 replace

#5


你替换的规则是怎么样?
是在mystr.ini中的任一行数据str,
把这三种组合"AA" & str,str & "BB" 和str & "CC899"的字符串
都替换为""吗?

#6


是这样,strcontent里面,不一定有这个关键字组合,所以需要判断一下,有这个关键字组合则过滤掉..即,if instr(strcontent,strtemp)>0 then end..

这6000多个关键字,在一个strcontent里,有可能没有一条符合条件,有可能有多条符合条件..但却需要全部判断,过滤一遍.

#7


TO:clear_zero(clear_zero) 
谢谢你的意见,我说的是有问题..

这个判断应该放到最后,前面应该放str & "BB" 等等组合的关键字过滤...
if instr(strcontent,str)>0 then
  strcontent=replace(strcontent,str,"")
end if

#8


TO:cangwu_lee(橙子)
直接替换会快嘛,,谢谢,,我试一下.

#9


For VB5 user:
Public Sub ReplaceAll(ByRef sOrigStr As String,  _
            ByVal sFindStr As String, _
            ByVal sReplaceWithStr As String, _
            Optional bWholeWordsOnly As Boolean)
'
' Replaces all occurances of sFindStr with sReplaceWithStr
'
    Dim lPos As Long
    Dim lPos2 As Long
    Dim sTmpStr As String
    Dim bReplaceIt As Boolean
    Dim lFindStr As Long


    On Error GoTo vbErrorHandler

    lFindStr = Len(sFindStr)

    lPos2 = 1
    bReplaceIt = True
    sTmpStr = sOrigStr

    Do
        lPos = InStr(lPos2, sOrigStr, sFindStr)
        If lPos = 0 Then
            Exit Do
        End If
        If bWholeWordsOnly Then
            On Error Resume Next
            If lPos = 1 Or (Mid$(sOrigStr, lPos - 1, 1) = " ") Then
                If (Mid$(sOrigStr, lPos + lFindStr, 1) = " ") Or Mid$(sOrigStr, lPos + lFindStr + 1, 1) = "" Then
                    bReplaceIt = True
                Else
                    bReplaceIt = False
                End If
            End If
        End If
        If bReplaceIt Then
            If lPos > 1 Then
                sTmpStr = Left$(sOrigStr, lPos - 1)
            Else
                sTmpStr = ""
            End If
            sTmpStr = sTmpStr & sReplaceWithStr
            sTmpStr = sTmpStr & Mid$(sOrigStr, lPos + lFindStr, Len(sOrigStr) - (lPos + lFindStr - 1))
            sOrigStr = sTmpStr
        End If
        lPos2 = lPos + 1
    Loop
    sOrigStr = sTmpStr
    Exit Sub

vbErrorHandler:
    Err.Raise Err.Number, "StrHandler ReplaceAll", Err.Description


End Sub

#10


TO:junki(『.NET技术争霸天下』) 
你好,我说的意思是,有N多种组合,如果符合条件就要过滤掉,一条长字符串中,有可能一条也没有符合的组合关键字.但是6000多条str也要全运行一圈

#11


不要判断,直接调用 replace

#12


这种问题想快都难。

6000条内容,再加上N种组合,6000*N 次循环,还是处理VB不善长的大字符串处理,加进度条吧!

另外,少一个 instr() 判断应该会快许多。

#13


不知道楼主什么意图,在测试VB的效率?

如果是真想实用,单看楼主写的那些,简直是天方夜谭,程序绝对没这么写的.

#14


replace函数

#15


楼主考虑一下正则表达式

--------
www.vicmiao.com
努力就有美好时光!

#16


vb里不可以用正则么?

#17


正则表达式

#18


可以将文件读入一个字符串变量,然后再对该字符串变量进行replace操作,如果应用中需要每一行的数据,再用split函数分解。这样避免在循环中频繁调用replace函数,replace函数可以将字符串中所有要替换的内容一次性完成。
希望这个思路与你的应用不冲突!

#19


这样:
每读出一句的判断还是要的。因为你的所有组合,都是包含 str 的,因此若长字符串不包含 str ,其他的所有操作都可以省掉,直接处理下一句。

F = FreeFile
Open app.path & "\mystr.ini" For Input As #F
Do Until EOF(F)
Line Input #F, str

if instr(strcontent,str) then
  strcontent=replace(strcontent,"AA" & str,"")
  strcontent=replace(strcontent,str & "BB","")
  strcontent=replace(strcontent,str & "CC" & "899","")
  strcontent=replace(strcontent,str,"")
end if

loop
Close #F

#20


AA,BB.....这些处理一次就行了吧?为什么要放在每一个line中?

#21


AA,BB这些也是变量?

#22


vb 中可以用正则,不过这个是字符替换,与正则不相干吧?

#23


AA,BB.....这些处理一次就行了吧?为什么要放在每一个line中?
-------------------------
哦,是我糊涂了 !

#24


TO:VBAdvisor(Sunlight):
这个函数不错,但过滤的关键字组合太多,也是同样的问题,反应慢.

#25


TO:theforever(碧海情天)
呵呵,不是测CPU呀..不是没事干..

#26


我知道我的方法的确不可取,效率低下...所以请大家支招..

#27


都成头条了!

#28


直接用REPLACE替换,,效率差不多,慢呢.

#29


TO:fxy_2002(阿勇)
这种问题想快都难。
6000条内容,再加上N种组合,6000*N 次循环,还是处理VB不善长的大字符串处理,加进度条吧!
另外,少一个 instr() 判断应该会快许多

-------------------------
是呀,现在希望以最快的速度处理完这个长字符串,把里面不需要的过滤掉.加进度条没意义了.
因为内容里的关键字未知,所以必须得把关键字组合起来全部循环一圈..

#30


呵呵,感谢大家的关注..60太少了
我决定,如果有好的解决办法,我会另开贴
提供最好的解决办法的GG,MM,将直接得到100分..跟贴者有分..

#31


不可能有大幅度的改进。字符串处理本身就很慢。再就上要对一个长字符串反复处理。

能否说说你要干什么?看看能否采用其他方案。

#32


想不通为什么楼主要一行一行的读文件,慢的不是处理字符串,而是循环读文件。

    Dim i       As Integer
    Dim v()     As Byte
    Dim s       As String
    
    i = FreeFile()
    
    Open App.Path & "\mystr.ini" For Binary As i
        ReDim v(LOF(i) - 1)
        Get i, , v()
    Close i
    
    s = StrConv(v, vbUnicode)
    
    s = Replace(s, "AA", "")
    s = Replace(s, "BB", "")
    s = Replace(s, "CC899", "")
    ' ...

你用这种方式来看看速度如何。

#33


谁让你不用VC写...

#34


VC也差不多,关键是要用什么方法来写

#35


呵呵,有些同学看代码不仔细啊!
楼主的目的显然不是要处理 mystr.ini 这个文件,而是要使用它里面内容作为的配对条件。所以一次性读取文件和一行行读取差距不会太明显。

of123 的方法是可以改进不少的,因为 str 如果不存在,其它的配对就不会存在。加一个判断后能大幅减速少判断次数!!

加进度条不会增加处理速度,但能使界面友好,感觉就会“快”一些。关键字数量未知很容易解决,先计算出 ini 文件的行数就可以了。

#36


接着fj182(阿花) 的写下去
dim b() as string
dim i as long
dim u as long
b=split(s,vbcrlf)
u=ubound(b)
for i=0 to u
 strcontent=b(i)
  
next i
用这方法得到的strcontent和楼主在do循环中的strcontent有什么区别?
正如楼上所说,楼主不是要处理mystr.ini文件,但是,首先,用fj182(阿花) 的方式与每行读取的方式与逐行读文件的方式速度不在一个数量级,其二,避免了在循环中用replace,这肯定可以加快处理速度的,即使后面再用循环取strcontent,也只是相当于楼主的do循环次数,但少了replace操作。

#37


改正:
正如楼上所说,楼主不是要处理mystr.ini文件,但是,首先,用fj182(阿花) 的方式与逐行读文件的方式速度不在一个数量级,其二,避免了在循环中用replace,这肯定可以加快处理速度的,即使后面再用循环取strcontent,也只是相当于楼主的do循环次数,但少了replace操作。

#38


不知道楼主的主要目的是什么,按照楼主的想法,首先去掉"AA" & str,再str & "BB",但是如果有这样的情况,即"A" & str & "BB""A" & str,如果先找"AA" & str则找不到,再找str & "BB",找到并置空,而这个时候"AA" & str却出现了。这样楼主的程序就会出现问题。因此每一行只有在所有的关键字都找不到的情况才能认为ok了,这样无疑更加大了计算量。所以我觉得楼主还是应该把真正的相关需求说出来,看看有没有其他比较好的方法把问题绕过去,否则就是钻入死胡同了。

#39


我再说一下我的目的:
比如:
我一天中,要处理几万条内容
在mystr.ini里面,汇集了部分需要过滤的关键字,这是在以前的内容里找出来的
每行是一个关键字,如,第一行是北京,第二行是上海,第三行是天津....

IF内容里,有与mystr.ini里的关键字相匹配的字符串,THEN就要过滤掉
IF内容里,没有与mystr.ini里的关键字相匹配的,THEN判断,不用过滤.

如果想知道每条内容里,有没需要过滤的字符串,那么就得与mystr.ini里的全部关键字符串进行判断,全部循环一遍.
循环每个关键字时,还要加其他的组合,进行判断,过滤.

代码如下:大家看仔细了..

处理其中的一条内容
mystr.ini里面是关键字,每行一个关键字
strcontent=此内容长字符串.
str=关键字

  F = FreeFile
  Open app.path & "\mystr.ini" For Input As #F
    Do Until EOF(F)
      Line Input #F, str

      ''其他字符与str组合,再过滤

      ''组合过滤1
      strtemp= "AA" & str
      if instr(strcontent,strtemp)>0 then
        strcontent=replace(strcontent,strtemp,"")
      end if

      ''组合过滤2
      strtemp= str & "BB" 
      if instr(strcontent,strtemp)>0 then
        strcontent=replace(strcontent,strtemp,"")
      end if

      ''组合过滤3
      strtemp= str & "CC" & "899"
      if instr(strcontent,strtemp)>0 then
        strcontent=replace(strcontent,strtemp,"")
      end if

      ''组合过滤N

      ''组合过滤N+1
      ......
      ......
      ......
      ......
      ......组合过滤比较多

      ''直接将str替换成空
      if instr(strcontent,str)>0 then
        strcontent=replace(strcontent,str,"")
      end if

    Loop

  Close #F

在mystr.ini里,每行是一个关键字,大概有6000行.全部循环完,感觉非常慢.请问有什么好一点办法嘛???

再说说加组合的目的:
比如关键字='北京'时,内容里有可能存在'AA北京'或者'北京BB',这时需要替换为空.
因为关键字的不确定性,所以加了IF ... THEN 判断,再使用REPLACE替换.



#40


大家不要再考虑此代码的逻辑问题
还有'AA','BB'的前后顺序问题.

此代码只是想表达我的意图.

我有过的想法:
1.如果循环到符合条件的关键字,替换为空,然后跳出DO循环,继续下一条内容
因为每条内容里最多有一次符合条件的关键字或者组合
但是,在内容里如果没有符合的,str肯定还是要全部循环全.
其实大部分内容还是不需要过滤的.

2.将str关键字存到数组里,循环,判断,感觉还是慢

2.大家用过哈希表嘛.

#41


需要关注的:

hn123(苗濤[www.vicmiao.com]) :
楼主考虑一下正则表达式

--------
www.vicmiao.com
努力就有美好时光!
-----------------------------------------------------------------------
VBToy(无证编程):
可以将文件读入一个字符串变量,然后再对该字符串变量进行replace操作,如果应用中需

要每一行的数据,再用split函数分解。这样避免在循环中频繁调用replace函数,replace

函数可以将字符串中所有要替换的内容一次性完成。
希望这个思路与你的应用不冲突!

-----------------------------------------------------------------------
of123() :
这样:
每读出一句的判断还是要的。因为你的所有组合,都是包含 str 的,因此若长字符串不包

含 str ,其他的所有操作都可以省掉,直接处理下一句。

F = FreeFile
Open app.path & "\mystr.ini" For Input As #F
Do Until EOF(F)
Line Input #F, str

if instr(strcontent,str) then
  strcontent=replace(strcontent,"AA" & str,"")
  strcontent=replace(strcontent,str & "BB","")
  strcontent=replace(strcontent,str & "CC" & "899","")
  strcontent=replace(strcontent,str,"")
end if

loop
Close #F

-----------------------------------------------------------------------
fj182(阿花):
想不通为什么楼主要一行一行的读文件,慢的不是处理字符串,而是循环读文件。

    Dim i       As Integer
    Dim v()     As Byte
    Dim s       As String
    
    i = FreeFile()
    
    Open App.Path & "\mystr.ini" For Binary As i
        ReDim v(LOF(i) - 1)
        Get i, , v()
    Close i
    
    s = StrConv(v, vbUnicode)
    
    s = Replace(s, "AA", "")
    s = Replace(s, "BB", "")
    s = Replace(s, "CC899", "")
    ' ...

你用这种方式来看看速度如何。

-----------------------------------------------------------------------
fxy_2002(阿勇):
呵呵,有些同学看代码不仔细啊!
楼主的目的显然不是要处理 mystr.ini 这个文件,而是要使用它里面内容作为的配对条件

。所以一次性读取文件和一行行读取差距不会太明显。

of123 的方法是可以改进不少的,因为 str 如果不存在,其它的配对就不会存在。加一个

判断后能大幅减速少判断次数!!

加进度条不会增加处理速度,但能使界面友好,感觉就会“快”一些。关键字数量未知很容

易解决,先计算出 ini 文件的行数就可以了。
-----------------------------------------------------------------------
VBToy(无证编程):
接着fj182(阿花) 的写下去
dim b() as string
dim i as long
dim u as long
b=split(s,vbcrlf)
u=ubound(b)
for i=0 to u
 strcontent=b(i)
  
next i
用这方法得到的strcontent和楼主在do循环中的strcontent有什么区别?
正如楼上所说,楼主不是要处理mystr.ini文件,但是,首先,用fj182(阿花) 的方式与逐

行读文件的方式速度不在一个数量级,其二,避免了在循环中用replace,这肯定可以加快

处理速度的,即使后面再用循环取strcontent,也只是相当于楼主的do循环次数,但少了

replace操作。

-----------------------------------------------------------------------
VBAdvisor(Sunlight):
For VB5 user:
Public Sub ReplaceAll(ByRef sOrigStr As String,  _
            ByVal sFindStr As String, _
            ByVal sReplaceWithStr As String, _
            Optional bWholeWordsOnly As Boolean)

#42


如果想提速,就只能在VB的内置函数上下功夫了。这个6000*N的LOOP再减,也还是很大的。
重写一下INSTR函数,我记得网上有人贴过这个算法,速度会提高很多。

#43


看一下如下例子体会一下replace一次进行多次替换的效果:
Dim s As String
s = "adfasfsffsfsaf"
Debug.Print Replace(s, "a", "X")
相信上述例子中的替换速度比用下面的速度快
for i=1 to len(s)
   t=mid(s,i,1)
   t=replace(t,"a","X")
   newStr=newStr & t
next i

实际上就替换操作来说,本来只用调用N次的,但在楼主的思路中可能要调用6000*N次。这就像登山,有索道直接上山顶,但如果要绕着上去,无论是走路还是开车,也快不了的。

#44


我搞不懂楼主的逻辑关系。
1、将str替换成空
2、其他字符与str组合,再过滤
这第一步已经把str消灭了,后面的组合就不存在了。
strtemp= "AA" & str 
等于是 strtemp= "AA" & "" 
等于是 strtemp= "AA"
楼主可能是要先消灭组合的,最后消灭str。如果是这样,又有一个麻烦,"AA" & str & "BB",怎么考虑?

#45


1、其实慢的不是比较的速度,而是字符串被改变重新分配内存的速度。因此建议楼主使用定长字符串,足够空间的定长字符串,这肯定会提高速度。象strcontent就可以声明为全局的,减少临时字符串的使用。
2、再就是尽力不使用会产生临时字符串的函数。比如类似strcontent = replace()。可以使用Instr函数替代,找到位置后用自己的replace函数。自己的replace函数使用copymemory,速度是很快的。总之就是减少内存分配的次数。
3、另外还有一个办法就是优化关键字数据结构。这个方法很多的,比如树状结构。

#46


YaDa() 看错了吧,呵呵。
和我先前一样,以为这样只要处理一次AA、BB之类的就可以了。不过看到下面发现是先处理str和AA。BB之类的组合,最后再过虑掉str

#47


Split之后再进行Join

#48


回vbman2003(家人): 
看倒是没看错,只不过后来他改进了。
同意VBToy(无证编程):
“本来只用调用N次的,但在楼主的思路中可能要调用6000*N次”
Replace是很快的,我试过:200多K的文本,调用80次,替换了几千个数据,毒龙850CPU,一秒之内完成。

#49


LZ 请把你的源代码,和 INI 文件发送到 fengming@263.net

#50



TO fj182(阿花) ,VBToy(无证编程):

你们下面的代码,,运行到了最后,还是要想法替换的呀.我也试过,用的是数组,速度还是慢..

------------------------------------------------
    Dim i       As Integer
    Dim v()     As Byte
    Dim s       As String
    
    i = FreeFile()
    
    Open App.Path & "\mystr.ini" For Binary As i
        ReDim v(LOF(i) - 1)
        Get i, , v()
    Close i    
    s = StrConv(v, vbUnicode)

    Dim b() As String
    Dim ii As Long
    Dim u As Long
    b = Split(s, vbCrLf)
    u = UBound(b)
    For ii = 0 To u
        strcontent = b(ii)
        '''这里要进行组合,过滤,替换
        .................
        .................
    Next ii