首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

两个字符串比较函数的评估(仅比较是否相同,忽略大小写)解决思路

2012-02-21 
两个字符串比较函数的评估(仅比较是否相同,忽略大小写)两个使用汇编实现的忽略大小写的仅比较是否相同的字

两个字符串比较函数的评估(仅比较是否相同,忽略大小写)
两个使用汇编实现的忽略大小写的仅比较是否相同的字符串比较函数,如果是在实际应用当中使用,都会选择哪一个,为什么?这里假定两字符串长度相同(实际应用当中还有前一级函数处理长度问题)

一般地比较

Delphi(Pascal) code
function IsSameText(const Str1, Str2: PChar; Len: Cardinal): Boolean; assembler;asm        PUSH    EDI        PUSH    ESI        PUSH    EBX        MOV     ESI,EAX //Str1        MOV     EDI,EDX //Str2        MOV     EBX,ECX //Len        XOR     EAX,EAX        OR      ECX,ECX        JE      @@T        REPNE   SCASB   //扫描ESI/EDI指针指向的字符,当不相等的时候结束,否则扣减ECX计数,直到计数为0结束        SUB     EBX,ECX        MOV     ECX,EBX        MOV     EDI,EDX        XOR     EDX,EDX@@1:    REPE    CMPSB        JE      @@T        MOV     AL,[ESI-1] //AL = Str1[Index]        CMP     AL,'a'        JB      @@2        CMP     AL,'z'        JA      @@2        SUB     AL,20H  //To Upper@@2:    MOV     DL,[EDI-1] //DL = Str2[Index]        CMP     DL,'a'        JB      @@3        CMP     DL,'z'        JA      @@3        SUB     DL,20H  //To Upper@@3:    SUB     AL,DL        JE      @@1     //AL - DL = 0? NextChar:End (return False)@@F:    xor     EAX,EAX //False,EAX return 0        jmp     @@E@@T:    mov     EAX,1   //True,EAX return 1@@E:    POP     EBX        POP     ESI        POP     EDIend;


应用查表(实际上这个查表也可以应用于大小写转换)
Delphi(Pascal) code
function IsSameText(const Str1, Str2: PChar; Len: Cardinal): Boolean; assembler;asm        PUSH    EDI        PUSH    ESI        PUSH    EBX        MOV     ESI,EAX  //Str1        MOV     EDI,EDX  //Str2        MOV     EBX,ECX  //Len        XOR     EAX,EAX        OR      ECX,ECX        JE      @@T        REPNE   SCASB    //扫描ESI/EDI指针指向的字符,当不相等的时候结束,否则扣减ECX计数,直到计数为0结束        SUB     EBX,ECX        MOV     ECX,EBX        MOV     EDI,EDX        XOR     EDX,EDX        LEA     EBX,CS:[OFFSET @LOWER]@@1:    REPE    CMPSB        JE      @@T        MOV     AL,[ESI-1]     //AL = Str1[Index]        MOV     AL,[EBX + EAX] //AL = Lower[Ord(AL)]@@2:    MOV     DL,[EDI-1]     //DL = Str2[Index]        MOV     DL,[EBX + EDX] //DL = Lower[Ord(DL)]@@3:    SUB     AL,DL          //AL = AL - DL        JE      @@1            //AL = 0? NextChar: End (return false)@@F:    xor     EAX,EAX        jmp     @@E@@T:    mov     EAX,1@@E:    POP     EBX        POP     ESI        POP     EDI        RET@LOWER: DB 000h, 001h, 002h, 003h, 004h, 005h, 006h, 007h, 008h, 009h, 00ah, 00bh, 00ch, 00dh, 00eh, 00fh        DB 010h, 011h, 012h, 013h, 014h, 015h, 016h, 017h, 018h, 019h, 01ah, 01bh, 01ch, 01dh, 01eh, 01fh        DB 020h, 021h, 022h, 023h, 024h, 025h, 026h, 027h, 028h, 029h, 02ah, 02bh, 02ch, 02dh, 02eh, 02fh        DB 030h, 031h, 032h, 033h, 034h, 035h, 036h, 037h, 038h, 039h, 03ah, 03bh, 03ch, 03dh, 03eh, 03fh        DB 040h        //大写字母        //---------------------        (*DB 041h, 042h, 043h, 044h, 045h, 046h, 047h, 048h, 049h, 04ah, 04bh, 04ch, 04dh, 04eh, 04fh        DB 050h, 051h, 052h, 053h, 054h, 055h, 056h, 057h, 058h, 059h, 05ah*)        //=====================        //小写字母        //---------------------        DB 061h, 062h, 063h, 064h, 065h, 066h, 067h, 068h, 069h, 06ah, 06bh, 06ch, 06dh, 06eh, 06fh        DB 070h, 071h, 072h, 073h, 074h, 075h, 076h, 077h, 078h, 079h, 07ah        //=====================        DB 05bh, 05ch, 05dh, 05eh, 05fh        DB 060h        //---------------------        //小写字母        DB 061h, 062h, 063h, 064h, 065h, 066h, 067h, 068h, 069h, 06ah, 06bh, 06ch, 06dh, 06eh, 06fh        DB 070h, 071h, 072h, 073h, 074h, 075h, 076h, 077h, 078h, 079h, 07ah        //======================        DB 07bh, 07ch, 07dh, 07eh, 07fh        DB 080h, 081h, 082h, 083h, 084h, 085h, 086h, 087h, 088h, 089h, 08ah, 08bh, 08ch, 08dh, 08eh, 08fh        DB 090h, 091h, 092h, 093h, 094h, 095h, 096h, 097h, 098h, 099h, 09ah, 09bh, 09ch, 09dh, 09eh, 09fh        DB 0a0h, 0a1h, 0a2h, 0a3h, 0a4h, 0a5h, 0a6h, 0a7h, 0a8h, 0a9h, 0aah, 0abh, 0ach, 0adh, 0aeh, 0afh        DB 0b0h, 0b1h, 0b2h, 0b3h, 0b4h, 0b5h, 0b6h, 0b7h, 0b8h, 0b9h, 0bah, 0bbh, 0bch, 0bdh, 0beh, 0bfh        DB 0c0h, 0c1h, 0c2h, 0c3h, 0c4h, 0c5h, 0c6h, 0c7h, 0c8h, 0c9h, 0cah, 0cbh, 0cch, 0cdh, 0ceh, 0cfh        DB 0d0h, 0d1h, 0d2h, 0d3h, 0d4h, 0d5h, 0d6h, 0d7h, 0d8h, 0d9h, 0dah, 0dbh, 0dch, 0ddh, 0deh, 0dfh        DB 0e0h, 0e1h, 0e2h, 0e3h, 0e4h, 0e5h, 0e6h, 0e7h, 0e8h, 0e9h, 0eah, 0ebh, 0ech, 0edh, 0eeh, 0efh        DB 0f0h, 0f1h, 0f2h, 0f3h, 0f4h, 0f5h, 0f6h, 0f7h, 0f8h, 0f9h, 0fah, 0fbh, 0fch, 0fdh, 0feh, 0ffhend; 



[解决办法]
我觉得第一种方法好
它直接操作的是存储地址 基本上没有多余的东西
第二种方法里 有一个查表的过程 这样的话 时间复杂度会大点
向僵哥 学习
[解决办法]
就是这个
CMP AL,'a'
JB @@2
CMP AL,'z'
JA @@2
SUB AL,20H //To Upper
和这个
MOV AL,[EBX + EAX] //AL = Lower[Ord(AL)]
的效率问题吧。

速度的话,我想间接寻址应该比三次减法运算要快吧。不过目标字符串都是大写的话就只用一次减法运算了。
[解决办法]
@_@
[解决办法]
300分吓人啊
[解决办法]
不错。
[解决办法]
字少的前面快,字多的后面快,前一种跟delphi的差不多
[解决办法]
占位,学习
[解决办法]
查表有效率,和CRC32算法差不多,但是相应的,程序就会大一些,反之亦然
CRC32的查表法和直接计算法之间的关系和僵哥的这两个方法都是差不多的
[解决办法]
学习
[解决办法]
探讨
引用:
我觉得第一种方法好
它直接操作的是存储地址 基本上没有多余的东西
第二种方法里 有一个查表的过程 这样的话 时间复杂度会大点
向僵哥 学习

要不测试一下,用个几兆或者几十兆的文件

[解决办法]
弄个用例测一下就好了
[解决办法]

[解决办法]
看不懂汇编。
如果我自己写的话,大概就是这样:
const
CharsTable: array [Char] of Char;

initChars;
for I := #0 to #$FF do
CharsTable[i] := i;


sametext do:
for I := 0 to len - 1 do
[
result := CharsTable[Src[I]] = CharsTable[Dest[I]];
if not result then break;
]

估计是趋于第二种,如果是第一种,我会直接用CompareMem

[解决办法]
o_o
[解决办法]
MARK,学习
[解决办法]
哪个效率最快呢???
[解决办法]
这2段东西,无论从速度,空间上来看,都差不多,就速度而言,本来我还准备翻翻资料看看指令执行周期来计算一下,可楼主还提到流水线断流的问题,我也就放弃了。(那位仁兄有心可以在不考虑流水线问题先给一个执行指令周期来看看)。这个断流的问题加进来太麻烦了,就第一段代码而言,出现断流的情况无非是,数字,大写,其他字符,在一般情况下,小写英文出现的几率应该比较多吧,当然如果是中文,跳转就比较多了,但每次跳转的时候又有3条指令不会去执行,问题是对于你用的cpu来说流水线有几级?4级,5级,还是更多。所以我认为这样是没有办法计算的。这只能是估计了,大概,也许,可能,第二段代码在多数情况下会运算快一点吧。可是能快多少,我恐怕到了几十兆也就毫秒的差别吧,要是再大的话,让用户等上2个小时和等上3个小时对用户来说也没有多大区别了,还不如配一块高点的cpu。
另外从空间上来说,如果真要考虑的话,大概要回到386年代了,这样的话速度上也就没有什么流水线问题了,一个破386就不要指望几十,几百兆的字符对比了吧。

当然,如果让我选,我就一般应用而言,2个都不选,因为这样的话,以后要修改的话,不太熟悉汇编的人不好改动程序。

ps:楼主大概把程序的中文注释拷错地方了吧 :)
[解决办法]
if str1 =str2 then ....
一群高手闲得没事做
鉴定完毕
[解决办法]
学习学习....!
[解决办法]
D 不是自己有嘛?
[解决办法]
看了一大堆的汇编
弄的有点稀里糊涂的
看来要回去好好的补习以下汇编
根据楼主的多方面考虑
我个人觉得看需要的是速度还是稳定性了


[解决办法]
学习
[解决办法]
学习 顶
[解决办法]

[解决办法]
求怜不如思进取
[解决办法]
我的天呀,这样也行
[解决办法]

探讨
引用:
我觉得第一种方法好
它直接操作的是存储地址 基本上没有多余的东西
第二种方法里 有一个查表的过程 这样的话 时间复杂度会大点
向僵哥 学习

要不测试一下,用个几兆或者几十兆的文件

[解决办法]
学习
[解决办法]
只要能够随机访问,浪费点内存没事
[解决办法]
向僵哥学习了
[解决办法]
Delphi(Pascal) code
function CompareText(const S1, S2: string): Integer; assembler;asm        PUSH    ESI        PUSH    EDI        PUSH    EBX        MOV     ESI,EAX        MOV     EDI,EDX        OR      EAX,EAX        JE      @@0        MOV     EAX,[EAX-4]@@0:    OR      EDX,EDX        JE      @@1        MOV     EDX,[EDX-4]@@1:    MOV     ECX,EAX        CMP     ECX,EDX        JBE     @@2        MOV     ECX,EDX@@2:    CMP     ECX,ECX@@3:    REPE    CMPSB        JE      @@6        MOV     BL,BYTE PTR [ESI-1]        CMP     BL,'a'        JB      @@4        CMP     BL,'z'        JA      @@4        SUB     BL,20H@@4:    MOV     BH,BYTE PTR [EDI-1]        CMP     BH,'a'        JB      @@5        CMP     BH,'z'        JA      @@5        SUB     BH,20H@@5:    CMP     BL,BH        JE      @@3        MOVZX   EAX,BL        MOVZX   EDX,BH@@6:    SUB     EAX,EDX        POP     EBX        POP     EDI        POP     ESIend;
[解决办法]
好帖子啊,顶一个
[解决办法]
探讨
Delphi(Pascal) codefunction CompareText(const S1, S2: string): Integer; assembler;
asm
PUSH ESI
PUSH EDI
PUSH EBX
MOV ESI,EAX
MOV EDI,EDX
OR EAX,EAX
JE @@0
MOV EAX,[EAX-4]
@@0: OR EDX,EDX
JE @@1
MOV EDX,[EDX-4]
@@1: MOV ECX,EAX
CMP ECX,E…

[解决办法]
先顶下,以后研究
[解决办法]
逆向一下别人现成的实现
然后根据需要改一改
[解决办法]
逆向Delphi的实现

[解决办法]
不是搞Delphi的,看不懂,学习。。。
[解决办法]
学习下~!!


[解决办法]
瞻仰高人!
[解决办法]
看看FastCode里面貌似有类似的函数代码

热点排行