找回密码
 加入
搜索
楼主: gto250

[效率算法] 字符串比较的效率问题[已解决]

 火... [复制链接]
发表于 2011-4-14 22:44:03 | 显示全部楼层
$begin = TimerInit()
$a = "123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430"
$b = "95412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123"
$aa = StringRegExp($a, '.{4}', 3)
$bb = StringRegExp($b, '.{4}', 3)
Dim $c
For $n = 1 To 500
        For $i = 0 To UBound($aa) - 1

                If $aa[$i] == $bb[$i] Then
                        $c &= "1"
                Else
                        $c &= "0"
                EndIf
        Next
Next
$dif = TimerDiff($begin)
MsgBox(0, "", $dif / 1000)
再改改~ 0.62秒左右

评分

参与人数 1金钱 +10 贡献 +5 收起 理由
gto250 + 10 + 5 谢谢

查看全部评分

发表于 2011-4-14 22:45:56 | 显示全部楼层
蛋蛋的位运算不知道符合LZ的要求不
发表于 2011-4-14 22:50:01 | 显示全部楼层
本帖最后由 netegg 于 2011-4-14 22:53 编辑

就算是这么用也没必要这样啊,后面的改成
                If $aa[$i] <> $bb[$i] Then
                        $dif = TimerDiff($begin)
                         exitloop 2
                EndIf
        Next
Next
MsgBox(0, "", $dif / 1000)
0.0019
就是不清楚楼主到底要什么结果
 楼主| 发表于 2011-4-14 22:51:59 | 显示全部楼层
我要的是对比完后的字符串,也就是输出的$C的结果。
采用正则,数组操作后我这里运行的时间是0.5秒左右!
我不知道蛋蛋的位运算是怎样的?

不过为什么不同的方法,效率会相差这么大?
各位兄弟能解释一下原理吗?
 楼主| 发表于 2011-4-14 22:53:33 | 显示全部楼层
写成这个样子,我只是想测试一下效率的问题!
发表于 2011-4-14 22:54:16 | 显示全部楼层
回复 19# gto250
要是这样的话,读取和输出字符串都快不了,afan的0.62秒已经很快了
发表于 2011-4-14 22:54:22 | 显示全部楼层
回复 19# gto250


    提升效率主要是 &= 的作用…
发表于 2011-4-14 22:57:08 | 显示全部楼层
所以刚才问lz是要比对的结果,还是要输出的结果,我那个只是比对,不管输出
 楼主| 发表于 2011-4-14 23:10:23 | 显示全部楼层
恩,我觉得也是!
原先我还想用memcmp来比较的,后来发现自己闹了个笑话
 楼主| 发表于 2011-4-14 23:37:08 | 显示全部楼层
$begin = TimerInit()
$a="123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430"
$b="95412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123"


$ta = DllStructCreate("byte ["&StringLen($a)/2&"]")
DllStructSetData($ta, 1, "0x"&$a)
$pa=DllStructGetPtr($ta)


$tb = DllStructCreate("byte ["&StringLen($b)/2&"]")
DllStructSetData($tb, 1, "0x"&$b)
$pb=DllStructGetPtr($tb)


For $n=1 To 500
Dim $c=""

For $x=1 To DllStructGetSize ( $ta ) 

$tBuff1 = DllStructCreate("byte[2]", $pa + ($x-1)*2)
$tBuff2 = DllStructCreate("byte[2]", $pb + ($x-1)*2)

If StringTrimLeft(DllStructGetData($tBuff1, 1),2)=StringTrimLeft(DllStructGetData($tBuff2, 1),2) Then
        $c&="0"
Else
        $c&="1"
EndIf
Next
Next
$dif = TimerDiff($begin)
 
MsgBox(0,"",$dif/1000)


9秒多
看来还是数组的方式最快了!
发表于 2011-4-14 23:47:17 | 显示全部楼层
没人回答我我本子为什么比你们的慢那么多的问题啊,4G 双核2.5
发表于 2011-4-15 00:55:16 | 显示全部楼层
第一个写的代码与AFAN的16楼一模一样.
还是给个另类的思路,将字符串转化为数字进行比较.效率应该略低.
$begin = TimerInit()
$a="123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430123456789012345698765432107654301234567890123456987654321076543012345678901234569876543210765430"
$b="213495412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123580125789685469870125493159541235801257896854698701254931595412358012578968546987012549315954123"
Local $Array_A=StringRegExp(StringUpper($a),'.{4}',3)
Local $Array_B=StringRegExp(StringUpper($b),'.{4}',3)
local $c

for $i =0 to UBound($Array_A)-1
        $Array_A[$i]=cover($Array_A[$i])
        $Array_B[$i]=cover($Array_B[$i])
Next

For $n=1 To 500
        for $i=0 to UBound($Array_A)-1
                if $Array_A[$i]=$Array_B[$i] Then
                        $c&=1
                Else
                        $c&=0
                EndIf                        
        Next
$dif = TimerDiff($begin)
Next
MsgBox(0,"",$dif/1000)

func cover($string)
        local $number
        for $k=1 to 4
                $number+=Asc(StringMid($string,$k,1))*$k;给个*$k权值,避免出现如1234和2143位置不同但结果相同的情况
        Next
        return $number
EndFunc
发表于 2011-4-15 01:17:50 | 显示全部楼层
回复 27# 3mile

效率很高,但是下面的加权值的方式能不能保证真的没事啊
举例来说
1111处理结果为1+2+3+4=10
8100处理结果为8+2+0+0=10
是不是说你的判断就有问题呢?
发表于 2011-4-15 04:53:17 | 显示全部楼层
本帖最后由 pusofalse 于 2011-4-15 07:48 编辑

#include <lsasecur.au3>
 
Local $sText1 = "Text1"
Local $sText2 = "Text2"
 
Local $iTimerInit = TimerInit()

For $i = 1 to 500
        _CompareStringD($sText1, $sText2)
Next

MsgBox(0, TimerDiff($iTimerInit) / 1000, "")
 
 
Func _CompareStringD($sText1, $sText2)
        Local $tText1, $tText2, $iLen1, $iLen2, $iMaxLen, $iMinLen, $tResult
 
        $iLen1 = StringLen($sText1)
        $iLen2 = StringLen($sText2)
 
        If $iLen1 > $iLen2 Then
                $iMaxLen = $iLen1
        Else
                $iMaxLen = $iLen2
        EndIf
 
        $iMinLen = ($iLen1 + $iLen2 - $iMaxLen) * 8 / 8 + 8
 
        $tText1 = DllStructCreate("char Text[" & $iLen1 + 1 & "]")
        $tText2 = DllStructCreate("char Text[" & $iLen2 + 1 & "]")
 
        DllStructSetData($tText1, "Text", $sText1)
        DllStructSetData($tText2, "Text", $sText2)
 
        $tResult = DllStructCreate("ubyte BitFlags[" & Ceiling($iMaxLen / 4) & "]")
 
        DllCall("User32.dll", "none", "CallWindowProcA", _
                        "ptr", _MMX_CompareStringD(), _
                        "ptr", DllStructGetPtr($tText1), _
                        "ptr", DllStructGetPtr($tText2), _
                        "dword", $iMinLen, _
                        "ptr", DllStructGetPtr($tResult))
 
        Return DllStructGetData($tResult, "BitFlags")
EndFunc ;==>_CompareStringD
 
Func _MMX_CompareStringD()
        Local Static $pStartAddr, $bCode, $tBuffer
 
        If IsDllStruct($tBuffer) Then Return SetError(0, DllStructGetSize($tBuffer), $pStartAddr)
 
        $pStartAddr = __SeVirtualAlloc(1024)
 
        $bCode = "0x" & _
                "55" & _                        ; push          ebp
                "8BEC" & _                      ; mov           ebp, esp
                "8B4D10" & _                    ; mov           ecx, dword ptr [ebp+10]
                "C1E903" & _                    ; shr           ecx, 3
                "E32F" & _                      ; jecxz         $+2f
                "56" & _                        ; push          esi
                "8B7508" & _                    ; mov           esi, dword ptr [ebp+8]
                "57" & _                        ; push          edi
                "8B7D0C" & _                    ; mov           edi, dword ptr [ebp+c]
                "53" & _                        ; push          ebx
                "8B5D14" & _                    ; mov           ebx, dword ptr [ebp+14]
                "0F6F44CEF8" & _                ; movq          mm0, qword ptr [esi+ecx*8-8]
                "0F7644CFF8" & _                ; pcmpeqd       mm0, qword ptr [edi+ecx*8-8]
                "0F7EC2" & _                    ; movd          edx, mm0
                "88544BFE" & _                  ; mov           byte ptr [ebx+ecx*2-2], dl
                "0F73D020" & _                  ; psrlq         mm0, 20
                "0F7EC2" & _                    ; movd          edx, mm0
                "88544BFF" & _                  ; mov           byte ptr [ebx+ecx*2-1], dl
                "E2E2" & _                      ; loopd         $-1e
                "0F77" & _                      ; emms
                "5B" & _                        ; pop           ebx
                "5F" & _                        ; pop           edi
                "5E" & _                        ; pop           esi
                "5D" & _                        ; pop           ebp
                "C21000" & _                    ; ret           10
                "CCCC"
 
        $tBuffer = DllStructCreate("ubyte Code[64]", $pStartAddr)
        DllStructSetData($tBuffer, "Code", Binary($bCode))
 
        Return SetError(0, DllStructGetSize($tBuffer), $pStartAddr)
EndFunc ;==>_MMX_CompareStringD

评分

参与人数 1金钱 +10 贡献 +5 收起 理由
gto250 + 10 + 5 谢谢

查看全部评分

 楼主| 发表于 2011-4-15 07:18:15 | 显示全部楼层
本帖最后由 gto250 于 2011-4-15 07:29 编辑

P版的代码是循环1次的,还是500次的?
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-5-13 00:58 , Processed in 0.073302 second(s), 15 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表