請問一下有關取部分字串(字串分割)的問題 |
答題得分者是:maomfh
|
小蚊子
中階會員 ![]() ![]() ![]() 發表:55 回覆:267 積分:94 註冊:2002-06-08 發送簡訊給我 |
程式碼來源 : http://www.swissdelphicenter.ch/torry/showcode.php?id=2275
此程式用法 是要 "" 非常高速 """ 的處理字串 // after optimizations with delphi it comes a // time for some assembler; also the memory // management (slow result allocation) has been // taken care of... // note : You MUST have the following global // variables : // var // Splitresult : Array[0..1023] of Char; // P_SplitResArray : Pointer; // then on form1.create assign Pointer : // P_SplitResArray := @SplitResult; // variable Splitresult will contain // the result after procedure has been completed procedure split5(const input: string; schar: Char; s: Byte); register; asm PUSH ECX PUSH EAX //registers : PUSH EDX //EAX = input PUSH EDI //DH = s TEST EAX, EAX //if input = '' then JZ @NoWords // goto @NoInput @WeHaveIt:MOV DH, CL //DL = schar MOV EDI, EAX //EDI := Addr(input); MOV ECX, [EDI-4] //ECX := length(input); @GoGo: MOV AL, DL //AL := Schar; CMP DH, 2 //IF DH = 2 then JE @StartCo // goto @StartCo MOV AH, 2 //AH (upper 8 bits of AX) will be our separator counter initial value is 2, max 256 @Lop: INC AH //AH := AH 1 REPNE SCASB //while (EDI^<>AL) and (ECX>0) begin INC EDI; DEC ECX; end; CMP AH, DH //if AH < DH then JB @Lop // goto @Lop TEST ECX, ECX //IF ECX > 0 then JG @StartCo // goto @StartCp @NoWords: MOV EDI,[P_SplitResArray] //result := MOV BYTE PTR [EDI], $0 // '' JMP @TotalEnd @StartCo: PUSH ESI MOV ESI, EDI MOV EDI, [P_SplitResArray] @CopyLoop:MOV AH, BYTE PTR[ESI 0] //32 bit aligned loop.. hopefully :) CMP AH, DL //1. test, 8 bits JE @Endword MOV BYTE PTR [EDI 0], AH INC EDI MOV AH, BYTE PTR[ESI 1] CMP AH, DL //2. test, 8 bits -> 16 bits.. JE @Endword MOV BYTE PTR [EDI 0], AH INC EDI MOV AH, BYTE PTR[ESI 2] CMP AH, DL //3. test, 8 bits -> 24 bits.. JE @Endword MOV BYTE PTR [EDI 0], AH INC EDI MOV AH, BYTE PTR[ESI 3] CMP AH, DL //4. test, 8 bits -> 32 bits.. JE @Endword MOV BYTE PTR [EDI 0], AH INC EDI ADD ESI, 4 SUB ECX, 4 CMP ECX, 0 JG @Copyloop @EndWord: MOV BYTE PTR [EDI], $0 //lisää nolla POP ESI @TotalEnd:POP EDI POP EDX POP EAX POP ECX @Final: RET // = = = = = = = = = = = = = = = = = = = = = = = = = STR := 'ABCD$123456$JDNDHURYR'; split5( STR , '$' , 0 ); showmessage(Splitresult); 會傳回 123456 想請問 split5( const input: string; schar: Char; s: Byte); 問 1 : input 前加 const 的用意??? 我試過,有加 const 與 不加,似乎必影響結果 問 2 : s 變數的作用是..... 我用 0 或 1 都不影響結果. 謝謝您 |
shunaaron
高階會員 ![]() ![]() ![]() ![]() 發表:13 回覆:94 積分:106 註冊:2006-10-06 發送簡訊給我 |
|
maomfh
初階會員 ![]() ![]() 發表:3 回覆:10 積分:27 註冊:2008-01-05 發送簡訊給我 |
問 1 : input 前加 const 的用意??? 我試過,有加 const 與 不加,似乎必影響結果
答 1 : (1) 加 const 代表是一個常數變數, 則函數內不可更動該參數的數值, 否則 compiler 會報錯, 無法通過編譯, 好處是,不會因自個兒不小心,動到來源參數的內容了. (2) 呼叫需傳入 有const 為參數的函數, 則compiler 可以不須再產生一個暫時變數, 這樣可以加速程式速度,也減少堆疊的耗用. 問 2 : s 變數的作用是..... 我用 0 或 1 都不影響結果. 答 2: s 變數是用來選取第幾個分割字串的, 但對原程式有些不明白, 傳入 0, 1 都會傳回第一分割字串, 但傳入2, 3, 4, 5 會分別傳回 第 0, 1,2,3個分割字串, 例如 : 'ABCD$123456$JDNDHURYR 0 : '123456' 1 : '123456' 2 : 'ABCD' 3 : '123456' 4 : 'JDNDHURYR' 5~255 : '' 傳回空字串
------
Maomfh |
roviury
一般會員 ![]() ![]() 發表:3 回覆:49 積分:15 註冊:2008-08-28 發送簡訊給我 |
用const ...:string在asm中很重要喔..
delphi都幫你搞好, 其實在asm中,不使用const的string,只是得到一個地址,還需要進一步存取 所以非必要就不要使用沒有const的 100%能夠加快速度 不過回傳很怪 * split5( STR , '$' , 0 )=123456; * split5( STR , '$' , 1 )=123456; 下面才正常 split5( STR , '$' , 2 ); split5( STR , '$' , 3 ); split5( STR , '$' , 4 ); 上樓也提到這個問題吧.. 這個問題很重要...沒解決好..這個函數就是失敗 另外,回傳值也十分不方便,又要作出更多的處理,即使多麼快也沒有用 我給一個相同功能的給你,短小快捷 function split6(const input: string; schar: Char; s: cardinal):string; var i,k:cardinal; begin k:=0; for i := 0 to length(input)-1 do begin if input[i 1]=schar then begin if s=0 then begin result:=copy(input,k 1,i-k 1); exit; end; dec(s); k:=i 1; end; end; result:=copy(input,k 1,i-k 1); end; STR := 'ABCD$123456$JDNDHURYR'; showmessage(split6( STR , '$' , 2 )); //JDNDHURYR 你喜歡速度就自己測試吧...一定不會慢 (你會留意到我寫的時候把s改成cardinal,你要處理大字串的話,byte一定不夠用) STR := 'ABCD$123456$JDNDHURYR'; showmessage(split6( STR , '$' , 100 )); //3或以後都會出現JDNDHURYR |
eaglewolf
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:4 回覆:268 積分:429 註冊:2006-07-06 發送簡訊給我 |
改一下紅色字的部份
傳0回傳 ABCD 傳1回傳123456 傳2回傳JDNDHURYR 傳3以上回傳 空字串 ===================引 用 小蚊子 文 章=================== 程式碼來源 : http://www.swissdelphicenter.ch/torry/showcode.php?id=2275 此程式用法 是要 "" 非常高速 """ 的處理字串 // after optimizations with delphi it comes a // time for some assembler; also the memory // management (slow result allocation) has been // taken care of... // note : You MUST have the following global // variables : // var // Splitresult : Array[0..1023] of Char; // P_SplitResArray : Pointer; // then on form1.create assign Pointer : // P_SplitResArray := @SplitResult; // variable Splitresult will contain // the result after procedure has been completed procedure split5(const input: string; schar: Char; s: Byte); register; asm PUSH ECX PUSH EAX //registers : PUSH EDX //EAX = input PUSH EDI //DH = s TEST EAX, EAX //if input = '' then JZ @NoWords // goto @NoInput @WeHaveIt:MOV DH, CL //DL = schar MOV EDI, EAX //EDI := Addr(input); MOV ECX, [EDI-4] //ECX := length(input); @GoGo: MOV AL, DL //AL := Schar; MOV AH, 0 //AH (upper 8 bits of AX) will be our separator counter initial value is 0 @Lop: INC AH //AH := AH 1 REPNE SCASB //while (EDI^<>AL) and (ECX>0) begin INC EDI; DEC ECX; end; CMP AH, DH //if AH < DH then JB @Lop // goto @Lop TEST ECX, ECX //IF ECX > 0 then JG @StartCo // goto @StartCp @NoWords: MOV EDI,[P_SplitResArray] //result := MOV BYTE PTR [EDI], $0 // '' JMP @TotalEnd @StartCo: PUSH ESI MOV ESI, EDI MOV EDI, [P_SplitResArray] @CopyLoop:MOV AH, BYTE PTR[ESI 0] //32 bit aligned loop.. hopefully :) CMP AH, DL //1. test, 8 bits JE @Endword MOV BYTE PTR [EDI 0], AH INC EDI MOV AH, BYTE PTR[ESI 1] CMP AH, DL //2. test, 8 bits -> 16 bits.. JE @Endword MOV BYTE PTR [EDI 0], AH INC EDI MOV AH, BYTE PTR[ESI 2] CMP AH, DL //3. test, 8 bits -> 24 bits.. JE @Endword MOV BYTE PTR [EDI 0], AH INC EDI MOV AH, BYTE PTR[ESI 3] CMP AH, DL //4. test, 8 bits -> 32 bits.. JE @Endword MOV BYTE PTR [EDI 0], AH INC EDI ADD ESI, 4 SUB ECX, 4 CMP ECX, 0 JG @Copyloop @EndWord: MOV BYTE PTR [EDI], $0 //lis nolla POP ESI @TotalEnd:POP EDI POP EDX POP EAX POP ECX @Final: RET
------
先查HELP 再查GOOGLE 最後才發問 沒人有義務替你解答問題 在標題或文章中標明很急 並不會增加網友回答速度 Developing Tool: 1.Delphi 6 2.Visual Studio 2005 3.Visual Studio 2008 DBMS: MS-SQL
編輯記錄
eaglewolf 重新編輯於 2009-09-14 15:28:52, 註解 無‧
|
macchen
初階會員 ![]() ![]() 發表:66 回覆:102 積分:33 註冊:2006-07-07 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |