全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1955
推到 Plurk!
推到 Facebook!

StringReplace 特異功能

 
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-05-24 12:02:31 IP:61.66.xxx.xxx 未訂閱
原文討論請見 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=30931 開發版本:Delphi5 目的:在為轉換地址全形之用 說明:設定三組TstringList(請參閱Demo), 其中第三組是可以不換的字串 例如:四段 -> 如果正常操作下會被換成 4段 但如果想保有原來的字串, 則在第三組(DefPartten)填入 段, 則四不會被轉換 已知目前無法解決的如(假設"路"設為不轉) 1. 五福四路 轉出來為 5福四路 六合路 轉出來為 6合路 但為上述問題, 我設定另一組解法 flag= [frSelectLast] 台北市五福四路16巷 我設定不轉換字串為 "縣市路", flag= [frSelectLast] 則轉出來為台北市五福四路16巷, 也就是說系統會自動檢視不轉換字串在 原字串的最後的一個位置, 本例"路"為最後, 所以路以前不轉, 以後才轉 2. 但這又有一個問題, 如果為 台北市23鄰五福四路16巷=>台北市23鄰五福四路16巷 了 3.十, 無法同時轉換10或1, 舉例 十巷 轉出來可能為1巷(十->1)或10巷(十->10) (視NewPattern所定), 十一巷 轉出來可能為11巷(十->1)或101巷(十->10) 我先把這組放上, 如果各位前輩有更好的處理, 不吝指教 ps:如果要使用這組函數, 請把函數中的Memo給拿掉, 這只是我在追蹤測試用 另外, 不知有沒有人可以把這樣的功能轉入 M$SQL 的STOREPROCEDURE, 可以 變成SQL可以直接呼叫使用的哦! 發表人 - P.D. 於 2003/05/24 12:04:32
附加檔案:31033_AddrTran.zip
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-05-24 14:03:24 IP:218.16.xxx.xxx 未訂閱
我還沒下載來玩不過看了文後有一些小建議 1,2 將地址以 Keyword 分段,就如 縣市路 為不轉之Keyword 鄰段巷 為換的字串 換與不換便可以整段為準而不必只要之前貼著的數字為準,亦不會像第二個方法限死在某不轉之 Keyword 之便所有之前的都不轉 若最後的 Keyword 後還有文字,是獨立一段可預設轉或不轉 3 另建立一對照 TStringList 十=10 百=100 千=1000 萬=10000 用之前的數字要乘以StringList.Values[TheChar] 如三十八 之前找出了三 ->3, StringList.Values['十'] 是 10 --> 3 * 10 = 30 再加後面的 八-> 8 = 38 是比較煩,而且十萬以上不好攪,所以只是供參考一下。
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-05-25 16:40:29 IP:61.66.xxx.xxx 未訂閱
引言: 我還沒下載來玩不過看了文後有一些小建議 1,2 將地址以 Keyword 分段,就如 縣市路 為不轉之Keyword 鄰段巷 為換的字串 換與不換便可以整段為準而不必只要之前貼著的數字為準,亦不會像第二個方法限死在某不轉之 Keyword 之便所有之前的都不轉 若最後的 Keyword 後還有文字,是獨立一段可預設轉或不轉 這點我有想過, 以縣市路為keyword 但在設計恐十分難寫 在台灣為 縣市區鎮村埔里鄰路街段弄巷號樓 路有二~五字(如五福四路, 六合路, 三路, 一般都不換, 但要判斷路到底有多長 不是拿把尺量就可以, 如何才能判斷這個地址的路長度為多少是個難點! 而且每一筆的地址建立都沒有標準, 我會做這個東西是因為接了一個只是要轉 地址成為統一格式的案子, 看了他們提供的3000萬筆地址我才暈了頭! 不知 justmade兄有何高見!? 3 另建立一對照 TStringList 十=10 百=100 千=1000 萬=10000 用之前的數字要乘以StringList.Values[TheChar] 如三十八 之前找出了三 ->3, StringList.Values['十'] 是 10 --> 3 * 10 = 30 再加後面的 八-> 8 = 38 是比較煩,而且十萬以上不好攪,所以只是供參考一下。 這個在寫時, 我也有想過, 不過考慮在轉換的效能, 我不敢寫 因為取出三還必須由電腦以loop判斷三轉3, 如果一百零三那更困難!
aip999
初階會員


發表:10
回覆:63
積分:44
註冊:2002-03-29

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-05-27 00:28:59 IP:211.76.xxx.xxx 未訂閱
引言:
引言: 我還沒下載來玩不過看了文後有一些小建議 1,2 將地址以 Keyword 分段,就如 縣市路 為不轉之Keyword 鄰段巷 為換的字串 換與不換便可以整段為準而不必只要之前貼著的數字為準,亦不會像第二個方法限死在某不轉之 Keyword 之便所有之前的都不轉 若最後的 Keyword 後還有文字,是獨立一段可預設轉或不轉 這點我有想過, 以縣市路為keyword 但在設計恐十分難寫 在台灣為 縣市區鎮村埔里鄰路街段弄巷號樓 路有二~五字(如五福四路, 六合路, 三路, 一般都不換, 但要判斷路到底有多長 不是拿把尺量就可以, 如何才能判斷這個地址的路長度為多少是個難點! 而且每一筆的地址建立都沒有標準, 我會做這個東西是因為接了一個只是要轉 地址成為統一格式的案子, 看了他們提供的3000萬筆地址我才暈了頭! 不知 justmade兄有何高見!? 3 另建立一對照 TStringList 十=10 百=100 千=1000 萬=10000 用之前的數字要乘以StringList.Values[TheChar] 如三十八 之前找出了三 ->3, StringList.Values['十'] 是 10 --> 3 * 10 = 30 再加後面的 八-> 8 = 38 是比較煩,而且十萬以上不好攪,所以只是供參考一下。 這個在寫時, 我也有想過, 不過考慮在轉換的效能, 我不敢寫 因為取出三還必須由電腦以loop判斷三轉3, 如果一百零三那更困難!
最好是自己寫... 不要用StringReplace... 用那個速度會很慢.. 自己隨便寫應該都比他快很多吧@@..用pos 不要用TStringList
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-05-27 01:50:19 IP:61.66.xxx.xxx 未訂閱
引言: 最好是自己寫... 不要用StringReplace... 用那個速度會很慢.. 自己隨便寫應該都比他快很多吧@@..用pos 不要用TStringList
嗯! 不知 aip999 是否有更好的想法, 可否提供一二, 謝謝!
aip999
初階會員


發表:10
回覆:63
積分:44
註冊:2002-03-29

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-05-27 02:10:31 IP:211.76.xxx.xxx 未訂閱
引言:
引言: 最好是自己寫... 不要用StringReplace... 用那個速度會很慢.. 自己隨便寫應該都比他快很多吧@@..用pos 不要用TStringList
嗯! 不知 aip999 是否有更好的想法, 可否提供一二, 謝謝!
用while跑字串長度 如過字串中都是中文字就 i:=1; while(i128) then begin//是中文字 //這邊寫轉換 if (str[i] str[i 1]='一') ... inc(i); end else begin//是英文字還是數字還是... end; inc(i); end; 要是只是轉0123456789 i:=1; r:=''; while(i#162)and((str[i 1]>#174)and(str[i 1]<#185)) then begin r:=r char((byte(str[i 1])-127)); end; end; 我沒Test過... 只是線上打一打你自己改一改 要看速度可以用 T : DWORD T:=GetTickCount; ...這邊寫程式 //你上面是用Memo debug Memo1.Lines.Add(IntToStr(GetTickCount-T));
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-05-27 11:11:49 IP:61.66.xxx.xxx 未訂閱
引言: 用while跑字串長度 如過字串中都是中文字就 i:=1; while(i128) then begin//是中文字 //這邊寫轉換 if (str[i] str[i 1]='一') ... inc(i); end else begin//是英文字還是數字還是... end; inc(i); end; 要是只是轉0123456789 i:=1; r:=''; while(i#162)and((str[i 1]>#174)and(str[i 1]<#185)) then begin r:=r char((byte(str[i 1])-127)); end; end;
謝謝 aip999的說明, 這也是一個好方法, 不過我有一點的疑問 if (str[i] str[i 1]='一') ... 這個判斷式有幾個問題 1.if 的效能並不好, 所以如果大量使用if 會降低整個轉換效率, 筆數少的 話看不太出來, 筆數達到一定水準之上, 每一筆多耽0.001秒, 3000萬筆就多耗 3萬秒=8.3小時 2.由於轉換的字串項目(oldpattern)是未定, 對於 if 無法掌握, 除非再加上一 個loop
for j= 0 to oldpattern.count-1 do begin
  if (str[i] str[i 1]=oldpattern[j]) then begin
    ...轉換
    break;
   end;
end;
3.我必須有replaceall 功能, 如果用此法勢必增語法判斷的複雜度及時間
4.我測試StringReplace()最基本的方法轉換
oldparttern有0..9,O..九,-,之,樓,F,f,.
有兩個欄位要轉換
轉換10萬筆一共花了72秒(p4 2.4g)
用我上傳的方法一共花了45秒, 3000萬足足省了2.25小時
不過電腦有個特性會越轉越慢, 我測到的基數每150萬的速度約下降3%    以上提供給你參考
aip999
初階會員


發表:10
回覆:63
積分:44
註冊:2002-03-29

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-05-27 14:30:45 IP:211.76.xxx.xxx 未訂閱
引言:
引言: 用while跑字串長度 如過字串中都是中文字就 i:=1; while(i128) then begin//是中文字 //這邊寫轉換 if (str[i] str[i 1]='一') ... inc(i); end else begin//是英文字還是數字還是... end; inc(i); end; 要是只是轉0123456789 i:=1; r:=''; while(i#162)and((str[i 1]>#174)and(str[i 1]<#185)) then begin r:=r char((byte(str[i 1])-127)); end; end;
謝謝 aip999的說明, 這也是一個好方法, 不過我有一點的疑問 if (str[i] str[i 1]='一') ... 這個判斷式有幾個問題 1.if 的效能並不好, 所以如果大量使用if 會降低整個轉換效率, 筆數少的 話看不太出來, 筆數達到一定水準之上, 每一筆多耽0.001秒, 3000萬筆就多耗 3萬秒=8.3小時 2.由於轉換的字串項目(oldpattern)是未定, 對於 if 無法掌握, 除非再加上一 個loop
for j= 0 to oldpattern.count-1 do begin
  if (str[i] str[i 1]=oldpattern[j]) then begin
    ...轉換
    break;
   end;
end;
3.我必須有replaceall 功能, 如果用此法勢必增語法判斷的複雜度及時間
4.我測試StringReplace()最基本的方法轉換
oldparttern有0..9,O..九,-,之,樓,F,f,.
有兩個欄位要轉換
轉換10萬筆一共花了72秒(p4 2.4g)
用我上傳的方法一共花了45秒, 3000萬足足省了2.25小時
不過電腦有個特性會越轉越慢, 我測到的基數每150萬的速度約下降3%    以上提供給你參考
你不會以為TStringList 會比較快吧.. 所謂的replaceall一樣是把字串跑一便... 無論是用哪一種語言都一樣吧.. 如果你要區分哪些不要轉換,那就要用之前有個人說過的寫法 把路,段,...等等都先用pos 切斷,在轉換 然後到最後在 回去 你要跑3000萬筆@@...用TStringList會比自己寫的慢個5倍以上
系統時間:2024-07-05 0:51:50
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!