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
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
也许我分析错了,你再看看
实在不行就给客户一个进度条
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"的字符串
都替换为""吗?
是在mystr.ini中的任一行数据str,
把这三种组合"AA" & str,str & "BB" 和str & "CC899"的字符串
都替换为""吗?
#6
是这样,strcontent里面,不一定有这个关键字组合,所以需要判断一下,有这个关键字组合则过滤掉..即,if instr(strcontent,strtemp)>0 then end..
这6000多个关键字,在一个strcontent里,有可能没有一条符合条件,有可能有多条符合条件..但却需要全部判断,过滤一遍.
这6000多个关键字,在一个strcontent里,有可能没有一条符合条件,有可能有多条符合条件..但却需要全部判断,过滤一遍.
#7
TO:clear_zero(clear_zero)
谢谢你的意见,我说的是有问题..
这个判断应该放到最后,前面应该放str & "BB" 等等组合的关键字过滤...
if instr(strcontent,str)>0 then
strcontent=replace(strcontent,str,"")
end if
谢谢你的意见,我说的是有问题..
这个判断应该放到最后,前面应该放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
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也要全运行一圈
你好,我说的意思是,有N多种组合,如果符合条件就要过滤掉,一条长字符串中,有可能一条也没有符合的组合关键字.但是6000多条str也要全运行一圈
#11
不要判断,直接调用 replace
#12
这种问题想快都难。
6000条内容,再加上N种组合,6000*N 次循环,还是处理VB不善长的大字符串处理,加进度条吧!
另外,少一个 instr() 判断应该会快许多。
6000条内容,再加上N种组合,6000*N 次循环,还是处理VB不善长的大字符串处理,加进度条吧!
另外,少一个 instr() 判断应该会快许多。
#13
不知道楼主什么意图,在测试VB的效率?
如果是真想实用,单看楼主写的那些,简直是天方夜谭,程序绝对没这么写的.
如果是真想实用,单看楼主写的那些,简直是天方夜谭,程序绝对没这么写的.
#14
replace函数
#15
楼主考虑一下正则表达式
--------
www.vicmiao.com
努力就有美好时光!
--------
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
每读出一句的判断还是要的。因为你的所有组合,都是包含 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呀..不是没事干..
呵呵,不是测CPU呀..不是没事干..
#26
我知道我的方法的确不可取,效率低下...所以请大家支招..
#27
都成头条了!
#28
直接用REPLACE替换,,效率差不多,慢呢.
#29
TO:fxy_2002(阿勇)
这种问题想快都难。
6000条内容,再加上N种组合,6000*N 次循环,还是处理VB不善长的大字符串处理,加进度条吧!
另外,少一个 instr() 判断应该会快许多
-------------------------
是呀,现在希望以最快的速度处理完这个长字符串,把里面不需要的过滤掉.加进度条没意义了.
因为内容里的关键字未知,所以必须得把关键字组合起来全部循环一圈..
这种问题想快都难。
6000条内容,再加上N种组合,6000*N 次循环,还是处理VB不善长的大字符串处理,加进度条吧!
另外,少一个 instr() 判断应该会快许多
-------------------------
是呀,现在希望以最快的速度处理完这个长字符串,把里面不需要的过滤掉.加进度条没意义了.
因为内容里的关键字未知,所以必须得把关键字组合起来全部循环一圈..
#30
呵呵,感谢大家的关注..60太少了
我决定,如果有好的解决办法,我会另开贴
提供最好的解决办法的GG,MM,将直接得到100分..跟贴者有分..
我决定,如果有好的解决办法,我会另开贴
提供最好的解决办法的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", "")
' ...
你用这种方式来看看速度如何。
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 文件的行数就可以了。
楼主的目的显然不是要处理 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操作。
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操作。
正如楼上所说,楼主不是要处理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替换.
比如:
我一天中,要处理几万条内容
在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.大家用过哈希表嘛.
还有'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)
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函数,我记得网上有人贴过这个算法,速度会提高很多。
重写一下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次。这就像登山,有索道直接上山顶,但如果要绕着上去,无论是走路还是开车,也快不了的。
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",怎么考虑?
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、另外还有一个办法就是优化关键字数据结构。这个方法很多的,比如树状结构。
2、再就是尽力不使用会产生临时字符串的函数。比如类似strcontent = replace()。可以使用Instr函数替代,找到位置后用自己的replace函数。自己的replace函数使用copymemory,速度是很快的。总之就是减少内存分配的次数。
3、另外还有一个办法就是优化关键字数据结构。这个方法很多的,比如树状结构。
#46
YaDa() 看错了吧,呵呵。
和我先前一样,以为这样只要处理一次AA、BB之类的就可以了。不过看到下面发现是先处理str和AA。BB之类的组合,最后再过虑掉str
和我先前一样,以为这样只要处理一次AA、BB之类的就可以了。不过看到下面发现是先处理str和AA。BB之类的组合,最后再过虑掉str
#47
Split之后再进行Join
#48
回vbman2003(家人):
看倒是没看错,只不过后来他改进了。
同意VBToy(无证编程):
“本来只用调用N次的,但在楼主的思路中可能要调用6000*N次”
Replace是很快的,我试过:200多K的文本,调用80次,替换了几千个数据,毒龙850CPU,一秒之内完成。
看倒是没看错,只不过后来他改进了。
同意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
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
也许我分析错了,你再看看
实在不行就给客户一个进度条
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"的字符串
都替换为""吗?
是在mystr.ini中的任一行数据str,
把这三种组合"AA" & str,str & "BB" 和str & "CC899"的字符串
都替换为""吗?
#6
是这样,strcontent里面,不一定有这个关键字组合,所以需要判断一下,有这个关键字组合则过滤掉..即,if instr(strcontent,strtemp)>0 then end..
这6000多个关键字,在一个strcontent里,有可能没有一条符合条件,有可能有多条符合条件..但却需要全部判断,过滤一遍.
这6000多个关键字,在一个strcontent里,有可能没有一条符合条件,有可能有多条符合条件..但却需要全部判断,过滤一遍.
#7
TO:clear_zero(clear_zero)
谢谢你的意见,我说的是有问题..
这个判断应该放到最后,前面应该放str & "BB" 等等组合的关键字过滤...
if instr(strcontent,str)>0 then
strcontent=replace(strcontent,str,"")
end if
谢谢你的意见,我说的是有问题..
这个判断应该放到最后,前面应该放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
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也要全运行一圈
你好,我说的意思是,有N多种组合,如果符合条件就要过滤掉,一条长字符串中,有可能一条也没有符合的组合关键字.但是6000多条str也要全运行一圈
#11
不要判断,直接调用 replace
#12
这种问题想快都难。
6000条内容,再加上N种组合,6000*N 次循环,还是处理VB不善长的大字符串处理,加进度条吧!
另外,少一个 instr() 判断应该会快许多。
6000条内容,再加上N种组合,6000*N 次循环,还是处理VB不善长的大字符串处理,加进度条吧!
另外,少一个 instr() 判断应该会快许多。
#13
不知道楼主什么意图,在测试VB的效率?
如果是真想实用,单看楼主写的那些,简直是天方夜谭,程序绝对没这么写的.
如果是真想实用,单看楼主写的那些,简直是天方夜谭,程序绝对没这么写的.
#14
replace函数
#15
楼主考虑一下正则表达式
--------
www.vicmiao.com
努力就有美好时光!
--------
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
每读出一句的判断还是要的。因为你的所有组合,都是包含 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呀..不是没事干..
呵呵,不是测CPU呀..不是没事干..
#26
我知道我的方法的确不可取,效率低下...所以请大家支招..
#27
都成头条了!
#28
直接用REPLACE替换,,效率差不多,慢呢.
#29
TO:fxy_2002(阿勇)
这种问题想快都难。
6000条内容,再加上N种组合,6000*N 次循环,还是处理VB不善长的大字符串处理,加进度条吧!
另外,少一个 instr() 判断应该会快许多
-------------------------
是呀,现在希望以最快的速度处理完这个长字符串,把里面不需要的过滤掉.加进度条没意义了.
因为内容里的关键字未知,所以必须得把关键字组合起来全部循环一圈..
这种问题想快都难。
6000条内容,再加上N种组合,6000*N 次循环,还是处理VB不善长的大字符串处理,加进度条吧!
另外,少一个 instr() 判断应该会快许多
-------------------------
是呀,现在希望以最快的速度处理完这个长字符串,把里面不需要的过滤掉.加进度条没意义了.
因为内容里的关键字未知,所以必须得把关键字组合起来全部循环一圈..
#30
呵呵,感谢大家的关注..60太少了
我决定,如果有好的解决办法,我会另开贴
提供最好的解决办法的GG,MM,将直接得到100分..跟贴者有分..
我决定,如果有好的解决办法,我会另开贴
提供最好的解决办法的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", "")
' ...
你用这种方式来看看速度如何。
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 文件的行数就可以了。
楼主的目的显然不是要处理 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操作。
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操作。
正如楼上所说,楼主不是要处理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替换.
比如:
我一天中,要处理几万条内容
在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.大家用过哈希表嘛.
还有'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)
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函数,我记得网上有人贴过这个算法,速度会提高很多。
重写一下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次。这就像登山,有索道直接上山顶,但如果要绕着上去,无论是走路还是开车,也快不了的。
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",怎么考虑?
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、另外还有一个办法就是优化关键字数据结构。这个方法很多的,比如树状结构。
2、再就是尽力不使用会产生临时字符串的函数。比如类似strcontent = replace()。可以使用Instr函数替代,找到位置后用自己的replace函数。自己的replace函数使用copymemory,速度是很快的。总之就是减少内存分配的次数。
3、另外还有一个办法就是优化关键字数据结构。这个方法很多的,比如树状结构。
#46
YaDa() 看错了吧,呵呵。
和我先前一样,以为这样只要处理一次AA、BB之类的就可以了。不过看到下面发现是先处理str和AA。BB之类的组合,最后再过虑掉str
和我先前一样,以为这样只要处理一次AA、BB之类的就可以了。不过看到下面发现是先处理str和AA。BB之类的组合,最后再过虑掉str
#47
Split之后再进行Join
#48
回vbman2003(家人):
看倒是没看错,只不过后来他改进了。
同意VBToy(无证编程):
“本来只用调用N次的,但在楼主的思路中可能要调用6000*N次”
Replace是很快的,我试过:200多K的文本,调用80次,替换了几千个数据,毒龙850CPU,一秒之内完成。
看倒是没看错,只不过后来他改进了。
同意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