作者JacobTai (不想跟世界说话)
看板Visual_Basic
标题Re: [VB6 ] 问一个有点笨的问题
时间Sat Mar 7 13:21:27 2009
※ 引述《MOONRAKER (㊣糜不有初,鲜克有终)》之铭言:
: : 推 JacobTai:漂亮...
: : → MOONRAKER:那麽复杂的函数呼叫26次 我不认为这哪里漂亮
: : → MOONRAKER:只是表面上比较好维护而已
: : → MOONRAKER:当然最好的办法是用scripting.regex
: for i=0 to 25,还不是要呼叫26次
: 复杂的是replace(),不是asc()
: 以长度 k 的字串来说,
: 用replace取代其中一个字元,每一个字元都要看过,复杂度 Θ(k)
: 跑26次,复杂度 Θ(26k)
: 本人的第一个写法(见第一篇回应),这是一个老屁股写法
: 只要从头到尾看字串一次,复杂度 Θ(k),而且一次replace都用不到
之所以评论 "漂亮" 原因有三...
1. 第一眼看到问题...
直觉反应也是在字串中一个字元一个字元比对...
ex:
for i = 1 to len(s)
if .... then ....
next i
看到 for loop 然後用 replace 的时候心中很讶异...
因为这是我从来没有想过的方法...
很高兴能在这边多学到一个思考方向...
2. 请先看一下原 PO 原始问题...
: replace(replace(string,"A","#"),"B","#").....
: 假设我要把所有字母都取代成那个符号
: 这样就要打好大一串
: 请问有比较简便的方式吗??
: 还是只能这样打?
简便的方式应该是用回圈简化程式吧...
原 PO 好像并没有太在意速度...
3. 在业界呆久了...常常得跟刚出学校的人争辩...
学校教导的是...程式要写得漂亮...
何谓漂亮? 省系统资源就叫漂亮...
如果我们现在用的是十年前的电脑...敝人非常赞同上述理论...
但是以现在的电脑速度来说...
敝人比较倾向於在 速度 跟 程式可读性 中取个平衡点...
replace 放在回圈中的写法 无可否认是非常直述的写法...
: 假设我要把所有字母都取代成那个符号
人脑怎麽想...程式怎麽写...
每个字母跑一次...答案就出来了...
字串中把每个字抓出来...再去判断是不是字母...
就原题目来说...思考方式是多转了一个圈...
写程式的人通常都不是维护程式的那一个...
要是 写程式的人 跟 维护程式的人 功力相同...一切好办...
很不幸的...每个人的功力都不同...
当程式需要维护的时候...使用者可是白领薪水坐在那等...
维护的人没办法立刻看懂程式找出错误...公司损失谁付?
所以敝人通常是要求写程式的人尽量写出易於维护的程式...
太多个人色彩的程式...比较适合个人工作室...
公司...通常会比较注重可读性以及易於维护性...
=================================================================
谈到程式效率...
s = s + "#"
当 s 是个少於十个字的字串...速度如飞...
当 s 内含大量文字...每多加一个字就得跟系统要一次记忆体...
除非确定是个小字串...不然省下的效率都在接字串时又浪费光了...
=================================================================
转成 Byte Array 之後再处理 也是我没想过的...
就算是个长字串...程式效能并没有被拖垮多少...
以下为抄袭修改之後的测试程式码...望原作见谅...
Private Sub test()
Dim x As String
Dim i As Double
Dim st As Long
Dim s As String
Dim j As Integer
For j = 1 To 2
If j = 1 Then
s = "aA...zZ "
Else
s = String(100, "aA...zZ ")
End If
st = Timer
For i = 1 To 300000
x = rep1(s)
Next
Debug.Print (Timer - st),
st = Timer
For i = 1 To 300000
x = rep2(s)
Next
Debug.Print (Timer - st),
st = Timer
For i = 1 To 300000
x = rep3(s)
Next
Debug.Print (Timer - st)
Next j
End Sub
Private Function rep1(ByVal src As String) As String
Dim i As Integer, b() As Byte
b = StrConv(src, vbFromUnicode)
Const c As Byte = 35 'Asc("#") = 35
For i = 0 To UBound(b)
'65 ~ 90 大写英文字母
'97 ~ 122 小写英文字母
If (b(i) >= 65 And b(i) <= 90) Or (b(i) >= 97 And b(i) <= 122) Then
b(i) = 35
End If
Next
rep1 = StrConv(b, vbUnicode)
End Function
Private Function rep2(ByVal src As String) As String
Dim i As Integer
For i = 65 To 90
src = Replace(src, Chr(i), "#")
Next
For i = 97 To 122
src = Replace(src, Chr(i), "#")
Next
rep2 = src
End Function
Private Function rep3(ByVal src As String) As String
Dim i As Integer
Dim s2 As String
Dim c As String
For i = 1 To Len(src)
c = Mid(src, i, 1)
If (c >= "A" And c <= "Z") Or (c >= "a" And c <= "z") Then
s2 = s2 & "#"
Else
s2 = s2 & c
End If
Next i
rep3 = s2
End Function
※ 编辑: JacobTai 来自: 70.68.113.130 (03/07 13:24)
1F:推 fumizuki:Replace 不用考虑了 跑了几十秒都跑不完... 03/07 16:04
2F:推 Y78:我後来改用Replace跑了一次 跑了10秒多 03/07 22:05