向大家请教提取字符串的最优算法 ( 积分: 100 )

  • 主题发起人 主题发起人 litong
  • 开始时间 开始时间
L

litong

Unregistered / Unconfirmed
GUEST, unregistred user!
我这个算法速度太慢了<br>//格式化数据【以 , 区分】<br>function getmaskstring(s:string;position:integer):string;<br>var<br> &nbsp;str:string;<br> &nbsp;i,len:integer;<br> &nbsp;begin<br> &nbsp;Str:='';<br> &nbsp;for i:=0 to position -1 do<br> &nbsp;begin<br> &nbsp;if(pos(',',s)&lt;=0) then<br> &nbsp;begin<br> &nbsp;str:=s;<br> &nbsp;break;<br> &nbsp;end;<br> &nbsp;str:=copy(s,1,pos(',',s)-1);<br> &nbsp;len:=length(str);<br> &nbsp;s:=copy(s,len+2,length(s)-len-1);<br> &nbsp;<br> &nbsp;end;<br> &nbsp;Result:=str;<br> &nbsp;end;
 
我这个算法速度太慢了<br>//格式化数据【以 , 区分】<br>function getmaskstring(s:string;position:integer):string;<br>var<br> &nbsp;str:string;<br> &nbsp;i,len:integer;<br> &nbsp;begin<br> &nbsp;Str:='';<br> &nbsp;for i:=0 to position -1 do<br> &nbsp;begin<br> &nbsp;if(pos(',',s)&lt;=0) then<br> &nbsp;begin<br> &nbsp;str:=s;<br> &nbsp;break;<br> &nbsp;end;<br> &nbsp;str:=copy(s,1,pos(',',s)-1);<br> &nbsp;len:=length(str);<br> &nbsp;s:=copy(s,len+2,length(s)-len-1);<br> &nbsp;<br> &nbsp;end;<br> &nbsp;Result:=str;<br> &nbsp;end;
 
舉個例子吧.看看你想達到什麼樣的效果.
 
for i:=0 to position -1 do<br> &nbsp;begin<br> &nbsp;if(pos(',',s)&lt;=0) then<br> &nbsp;begin<br> &nbsp;str:=s;<br> &nbsp;break;<br> &nbsp;end;<br>完全没有任何意义,自己研究。
 
因为数据量太大所以要求算法要速度快才行<br>举例 文本文件内容<br>1 sfksjhf,adadads,asadfw,sfsfsfds,aswqweqew,sdfsfsf,safdsadaz,adasdasd,adsadd<br>2 sfksjhf,adadads,asadfw,sfsfsfds,aswqweqew,sdfsfsf,safdsadaz,adasdasd,adsadd<br>3 sfksjhf,adadads,asadfw,sfsfsfds,aswqweqew,sdfsfsf,safdsadaz,adasdasd,adsadd<br>4 sfksjhf,adadads,asadfw,sfsfsfds,aswqweqew,sdfsfsf,safdsadaz,adasdasd,adsadd<br>5 sfksjhf,adadads,asadfw,sfsfsfds,aswqweqew,sdfsfsf,safdsadaz,adasdasd,adsadd<br>6 .............<br>...................<br>很多数据<br>想把以上数据以 “,” 分割导入 stringgrid 里 我的数据超过100行速度就很慢了【列在100个左右(就是 ,有100个)】
 
看你的代码想实现的是<br>s:='abc,defg,h,i,jk,lmnop';<br>getmaskstring(s,2)返回defg<br>getmaskstring(s,6)返回lmnop<br>s:='abcdefg';<br>getmaskstring(s,n)都返回abcedfg<br><br>function getmaskstring(s:string;position:integer):string;<br>var<br> &nbsp;i,j: Integer;<br> &nbsp;b:boolean;<br> &nbsp;str:String;<br>begin<br> &nbsp;j:=1;<br> &nbsp;b:=false;<br> &nbsp;str:='';<br> &nbsp;if position=j then b:=true;<br> &nbsp;for i:=1 to len(s) do<br> &nbsp;begin<br> &nbsp; &nbsp;if copy(s,i,1)=',' then <br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;if not b then<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;j:=j+1;<br> &nbsp; &nbsp; &nbsp; &nbsp;b:=true;<br> &nbsp; &nbsp; &nbsp;end<br> &nbsp; &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp; &nbsp;Result:=str;<br> &nbsp; &nbsp; &nbsp; &nbsp;exit; <br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;if b then str:=str+copy(s,i,1);<br> &nbsp;end;<br> &nbsp;if str='' then str=s;<br> &nbsp;Result:=str;<br>end;
 
&gt;&gt;&gt;&gt;想把以上数据以 “,” 分割导入 stringgrid 里 我的数据超过100行速度就很慢了<br><br>procedure getmaskstring(s:string;var ss:TStrings);<br>var<br> &nbsp;i: Integer;<br> &nbsp;str:String;<br>begin<br> &nbsp;for i:=1 to len(s) do<br> &nbsp;begin<br> &nbsp; &nbsp;if copy(s,i,1)=',' then <br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;ss.addstring(str);<br> &nbsp; &nbsp; &nbsp;str:='';<br> &nbsp; &nbsp;end<br> &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp;str:=str+copy(s,i,1);<br> &nbsp;end;<br> &nbsp;ss.addstring(str);<br>end; &nbsp;<br>...<br>var<br> &nbsp;sl:TStringList;<br>...<br>sl:=TStringList.create;<br>getmaskstring(s,sl);<br>//sl里就是存放着字符串集.<br>for i:=0 to sl.count-1 do<br> stringgrid.cell(1,i):=sl;
 
你的文本文件的每一行的格式都是一樣的吧?<br>建議你先建個數據庫表,用批量導入的方式把數據導入到表中:<br>BULK INSERT
FROM '路徑' WITH (FIELDTERMINATOR = ',')<br>然后再把數據轉移到StringGrid中吧
 
有个办法很简单的,cvs<br><br>我找找看 代码<br><br>xxx.CommaText := ('dfdfd,d,fd,f,f,d,d,fd,f,dsfdsddsd,d,fd,f,df,d,fd,f,d');
 
数据结构中有的啊,叫KMP算法啊<br>const<br> &nbsp;MAX_STRLEN = 255;<br>var<br> &nbsp;next: array[1..MAX_STRLEN] of integer;<br> &nbsp;str_s, str_t: string;<br> &nbsp;int_i: integer;<br><br><br>var<br> &nbsp;Form1: TForm1;<br><br>implementation<br><br>{$R *.dfm}<br><br>procedure get_nexst(t: string);<br>var<br> &nbsp;j, k: integer;<br>begin<br> &nbsp;j := 1; k := 0;<br> &nbsp;while j &lt; Length(t) do<br> &nbsp;begin<br> &nbsp; &nbsp;if (k = 0) or (t[j] = t[k]) then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;j := j + 1; k := k + 1;<br> &nbsp; &nbsp; &nbsp;next[j] := k;<br> &nbsp; &nbsp;end<br> &nbsp; &nbsp;else k := next[k];<br> &nbsp;end;<br>end;<br><br>function index(s: string; t: string): integer;<br>var<br> &nbsp;i, j: integer;<br>begin<br> &nbsp;get_nexst(t);<br> &nbsp;index := 0;<br> &nbsp;i := 1; j := 1;<br> &nbsp;while (i &lt;= Length(s)) and (j &lt;= Length(t)) do<br> &nbsp;begin<br> &nbsp; &nbsp;if (j = 0) or (s = t[j]) then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;i := i + 1; j := j + 1;<br> &nbsp; &nbsp;end<br> &nbsp; &nbsp;else j := next[j];<br> &nbsp; &nbsp;if j &gt; Length(t) then index := i - Length(t);<br> &nbsp;end;<br>end;<br><br><br><br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br> &nbsp;Pos<br> &nbsp;Edit3.Text:= IntToStr(index(Edit1.Text,Edit2.Text))<br>end;<br>这个算法没有问题的,什么时候给分呀?
 
试试这个的效果如何?<br><br>function TForm1.getmaskstring(s: string; position: integer;splitChar:Char = ','): string;<br>var<br> &nbsp;p,pRes : pchar;<br> &nbsp;i,iTmp,iLen : integer;<br> &nbsp;Addr_p,Addr_pRes : Cardinal;<br>begin<br> &nbsp;iLen := Length(s);<br> &nbsp;p := AllocMem(iLen + 1); &nbsp;//申请内存 ,用于保存源串<br> &nbsp;pRes := AllocMem(iLen + 1); //申请内存,用于保存返回子串<br> &nbsp;Addr_p := Cardinal(p); &nbsp;//保存地址<br> &nbsp;Addr_pRes := Cardinal(pRes); &nbsp;//保存地址<br> &nbsp;StrPCopy(p,s);<br> &nbsp;iTmp := 0; &nbsp; //第几个分割符号<br> &nbsp;Result := '';<br> &nbsp; &nbsp;For i := 0 to iLen - 1 do begin<br> &nbsp; &nbsp; &nbsp;if p^ = splitChar then begin &nbsp;//如果是分割符号,则增加其序号<br> &nbsp; &nbsp; &nbsp; &nbsp;if Position = iTmp then begin //需要返回的子串结束,退出循环<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Break;<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp; &nbsp;inc(iTmp); &nbsp;//增加分割符序号<br> &nbsp; &nbsp; &nbsp;end else begin &nbsp;//普通字符<br> &nbsp; &nbsp; &nbsp; &nbsp;if Position = iTmp then begin //如果是需要返回的子串部分<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pRes^ := p^; //从源串中复制一个字符<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;inc(Cardinal(pRes));//移动临时字符串指针<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp;end; //if p^<br><br> &nbsp; &nbsp; &nbsp;inc(Cardinal(p));//移动源字符串指针<br> &nbsp; &nbsp;end; &nbsp;//For i<br><br> &nbsp;Result := StrPas(PChar(Addr_pRes));<br> &nbsp;FreeMem(Pchar(Addr_pRes),iLen + 1); &nbsp; //释放内存<br> &nbsp;FreeMem(Pchar(Addr_p),iLen + 1); &nbsp; &nbsp; &nbsp;//释放内存<br>end;
 
把字串里的,用#13#10替换,然后装到MEMO里,一行一行的提取
 
type<br> &nbsp;TInstStr = procedure(const str: string);<br><br>procedure splitStr(const str: string; inst: TInstStr);<br>var<br> &nbsp;i, j: integer;<br>begin<br> &nbsp;i := 1;<br> &nbsp;for j:= 1 to length(str) do<br> &nbsp; &nbsp;if str[j] = ',' then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;inst(copy(str, i, j - i));<br> &nbsp; &nbsp; &nbsp;i := j + 1;<br> &nbsp; &nbsp;end;<br> &nbsp;if i &lt; length(str) then<br> &nbsp; &nbsp;inst(copy(str, i, length(str) - i));<br>end;<br><br>没测试,大概意思吧,很快的
 
要提高字符串操作效率,只要把字符串当做一个从1到length(字符串)的字符数组来操作就可以了,避免使用pos等函数和直接修改字符串的操作。
 
楼上高手们的答案,我有没有看错,这是stringgrid自带的功能。<br><br>var<br> &nbsp;sl:TStringList;<br><br> &nbsp;sl.Delimiter:=',';<br> &nbsp;sl.DelimitedText :='sfksjhf,adadads,asadfw,sfsfsfds,aswqweqew,sdfsfsf,safdsadaz,adasdasd,adsadd';<br><br><br>StringGrid1.Rows就是一个TStringList,所以<br><br>StringGrid1.Rows.Delimiter:=',';<br>StringGrid1.Rows[1].DelimitedText :='sfksjhf,adadads,asadfw,sfsfsfds,aswqweqew,sdfsfsf,safdsadaz,adasdasd,adsadd';<br><br>如果不是','分割,而是一些不显示的特殊字符,才可能需要写代码
 

Similar threads

I
回复
0
查看
658
import
I
I
回复
0
查看
584
import
I
I
回复
0
查看
596
import
I
I
回复
0
查看
516
import
I
后退
顶部