var i, j: integer; ArrStr: Array [0..10000] of string; begin j:=0; for i:=0 to 10000-1 do begin 也只有这种笨方法了,嘿嘿,本想写,但是发觉也很没效率,就不写了 end; end;
-----------排序开始-------------------------------------------------} procedure TForm_Report.sort_result; var i,j:integer; m_m:computername; begin for j:=0 to k_k_k-1 do for i:=0 to k_k_k-j do begin if outcome[i].Index<outcome[i+1].Index then begin m_m:=outcome[i]; outcome[i]:=outcome[i+1]; outcome[i+1]:=m_m; end; end; end; {-----------排序结束-------------------------------------------------}
type ComputerName= record Name:string; //存放名称 Index:integer;//对应个数 end; private stat_value:string; my_listview:array of string;//控制结果名称和出现次数 item_count:integer; //控制结果个数 outcome:array of ComputerName; k_k_k:integer;//主机名的个数 public {-----------合并相同项和统计其个数开始-------------------------------} procedure TForm_Report.stat_result; var i:integer; t_t:boolean; j:integer; begin for i:=0 to item_count-1 do begin t_t:=false; for j:=0 to item_count-1 do begin if ComPareText(my_listview[i],outcome[j].Name)=0 then begin t_t:=true; inc(outcome[j].Index); break; end ; end; if not t_t then begin outcome[k_k_k].name:=my_listview[i]; inc(outcome[k_k_k].Index); //标识出现个数 k_k_k:=k_k_k+1;//主机名的个数 end; end; end; {-----------合并相同项和统计其个数结束-------------------------------}
算法一,可能就是你那种:type TSortTable = class public Value: string; Count: Integer; end;procedure TForm1.Button1Click(Sender: TObject); var tls : Tstrings; dls : TStrings; i, b : Integer; st : TSortTable; d : dword; begin d := GetTickCount; memo1.lines.Clear; tls := tstringList.create; dls := tstringList.create; for i := 0 to 10000 do tls.Add(inttostr(Random(i))); for i := tls.Count - 1 downto 0 do begin if dls.IndexOf(tls.Strings[i]) = -1 then begin st := TSortTable.Create; st.Value := tls.Strings[i]; st.Count := 1; dls.AddObject(tls.Strings[i], st); end else TSortTable(dls.Objects[dls.IndexOf(tls.Strings[i])]).Count := TSortTable(dls.Objects[dls.IndexOf(tls.Strings[i])]).Count + 1; tls.Delete(i); end; d := GetTickCount - d; Label1.caption := 'Time:' + Inttostr(d); for i := 0 to dls.Count - 1 do begin dls.Strings[i] := TSortTable(dls.Objects[i]).Value + '|' + inttostr(TSortTable(dls.Objects[i]).Count); TSortTable(dls.Objects[i]).free; end; Memo1.Lines.Assign(dls); tls.Free; dls.free; end;总对10000个字符串统计,花了34秒;改进一下,先排序,然后再统计,13秒procedure TForm1.Button2Click(Sender: TObject); var tls : Tstrings; i : integer; begin listbox1.items.clear; listbox1.items.beginUpdate; tls := tstringList.create; for i := 0 to 10000 do tls.Add(inttostr(Random(i))); listbox1.Items.Assign(tls); tls.free; listbox1.Sorted := true; listbox1.items.endUpdate; end;procedure TForm1.Button3Click(Sender: TObject); var i : Integer; st : TSortTable; id : string; d : dword; begin d := GetTickCount; listbox2.items.clear; listbox2.items.beginUpdate; for i := listbox1.Items.Count - 1 downto 0 do begin id := listbox1.Items.Strings[i]; if listbox2.Items.IndexOf(id) = -1 then begin st := tSortTable.Create; st.Value := id; st.Count := 1; listbox2.Items.AddObject(id, st); end else TSortTable(listbox2.Items.Objects[listbox2.items.IndexOf(id)]).Count := TSortTable(listbox2.Items.Objects[listbox2.items.IndexOf(id)]).Count + 1; end; for i := 0 to listbox2.Items.Count - 1 do begin Listbox2.Items.Strings[i] := TSortTable(Listbox2.Items.Objects[i]).Value + '|' + inttostr(TSortTable(Listbox2.Items.Objects[i]).Count); TSortTable(Listbox2.Items.Objects[i]).free; end; listbox2.Sorted:=true; listbox2.items.endupdate; d := GetTickCount - d; Label2.caption := 'Time:' + Inttostr(d); end;组件用到 Button1: TButton; Memo1: TMemo; Label1: TLabel; ListBox1: TListBox; Button2: TButton; ListBox2: TListBox; Label2: TLabel; Button3: TButton;
改进的算法二,先排序,再统计;1.4秒:procedure TForm1.Button2Click(Sender: TObject); var tls : Tstrings; i : integer; begin listbox1.items.clear; listbox1.items.beginUpdate; tls := tstringList.create; for i := 0 to 10000 do tls.Add(inttostr(Random(i))); listbox1.Items.Assign(tls); tls.free; listbox1.Sorted := true; listbox1.items.endUpdate; end;procedure TForm1.Button3Click(Sender: TObject); var i, c, n : Integer; Tls:TStrings; st : TSortTable; id : string; b : string; d : dword; begin d := GetTickCount; Tls := Tstringlist.Create; Tls.Assign(Listbox1.Items); listbox2.items.clear; listbox2.items.beginUpdate; b := ''; //对比项目 n := 0; //索引位置 c := 0; //记数 for i := 0 to Tls.Count - 1 do begin id := Tls.Strings[i]; if id = b then //对比旧数据 c := c + 1; //如果相同则记数加一 if id <> b then //如果不相同则建立新的统计列 begin Inc(N,1); //增加索引位置 st := tSortTable.Create; st.Value := id; st.Count := 1; //初始记数1 listbox2.Items.AddObject(id, st); if c > 1 then TSortTable(Listbox2.Items.Objects[n - 2]).Count := c; //修改上一列的总数 c := 1; b := id; end; end; TSortTable(ListBox2.Items.Objects[n-1]).count :=c; //修改最后列总数 Tls.Free; for i := 0 to listbox2.Items.Count - 1 do begin //这里是列出项目,并加上数量 Listbox2.Items.Strings[i] := TSortTable(Listbox2.Items.Objects[i]).Value + '|' + inttostr(TSortTable(Listbox2.Items.Objects[i]).Count); TSortTable(Listbox2.Items.Objects[i]).free; end; listbox2.Sorted := true; listbox2.items.endupdate; d := GetTickCount - d; Label2.caption := 'Time:' + Inttostr(d); end; 排序+一次遍历
i, j: integer;
ArrStr: Array [0..10000] of string;
begin
j:=0;
for i:=0 to 10000-1 do
begin
也只有这种笨方法了,嘿嘿,本想写,但是发觉也很没效率,就不写了
end;
end;
procedure TForm_Report.sort_result;
var i,j:integer;
m_m:computername;
begin
for j:=0 to k_k_k-1 do
for i:=0 to k_k_k-j do
begin
if outcome[i].Index<outcome[i+1].Index then
begin
m_m:=outcome[i];
outcome[i]:=outcome[i+1];
outcome[i+1]:=m_m;
end;
end;
end;
{-----------排序结束-------------------------------------------------}
Name:string; //存放名称
Index:integer;//对应个数
end;
private
stat_value:string;
my_listview:array of string;//控制结果名称和出现次数
item_count:integer; //控制结果个数
outcome:array of ComputerName;
k_k_k:integer;//主机名的个数
public
{-----------合并相同项和统计其个数开始-------------------------------}
procedure TForm_Report.stat_result;
var i:integer;
t_t:boolean;
j:integer;
begin
for i:=0 to item_count-1 do
begin
t_t:=false;
for j:=0 to item_count-1 do
begin
if ComPareText(my_listview[i],outcome[j].Name)=0 then
begin
t_t:=true;
inc(outcome[j].Index);
break;
end ;
end;
if not t_t then
begin
outcome[k_k_k].name:=my_listview[i];
inc(outcome[k_k_k].Index); //标识出现个数
k_k_k:=k_k_k+1;//主机名的个数
end;
end;
end;
{-----------合并相同项和统计其个数结束-------------------------------}
TSortTable = class
public
Value: string;
Count: Integer;
end;procedure TForm1.Button1Click(Sender: TObject);
var
tls : Tstrings;
dls : TStrings;
i, b : Integer;
st : TSortTable;
d : dword;
begin
d := GetTickCount;
memo1.lines.Clear;
tls := tstringList.create;
dls := tstringList.create;
for i := 0 to 10000 do
tls.Add(inttostr(Random(i))); for i := tls.Count - 1 downto 0 do
begin
if dls.IndexOf(tls.Strings[i]) = -1 then
begin
st := TSortTable.Create;
st.Value := tls.Strings[i];
st.Count := 1;
dls.AddObject(tls.Strings[i], st);
end
else
TSortTable(dls.Objects[dls.IndexOf(tls.Strings[i])]).Count :=
TSortTable(dls.Objects[dls.IndexOf(tls.Strings[i])]).Count + 1;
tls.Delete(i);
end;
d := GetTickCount - d;
Label1.caption := 'Time:' + Inttostr(d); for i := 0 to dls.Count - 1 do
begin
dls.Strings[i] := TSortTable(dls.Objects[i]).Value +
'|' + inttostr(TSortTable(dls.Objects[i]).Count);
TSortTable(dls.Objects[i]).free;
end; Memo1.Lines.Assign(dls);
tls.Free;
dls.free;
end;总对10000个字符串统计,花了34秒;改进一下,先排序,然后再统计,13秒procedure TForm1.Button2Click(Sender: TObject);
var
tls : Tstrings;
i : integer;
begin
listbox1.items.clear;
listbox1.items.beginUpdate;
tls := tstringList.create;
for i := 0 to 10000 do
tls.Add(inttostr(Random(i)));
listbox1.Items.Assign(tls);
tls.free; listbox1.Sorted := true;
listbox1.items.endUpdate;
end;procedure TForm1.Button3Click(Sender: TObject);
var
i : Integer;
st : TSortTable;
id : string;
d : dword;
begin
d := GetTickCount;
listbox2.items.clear;
listbox2.items.beginUpdate;
for i := listbox1.Items.Count - 1 downto 0 do
begin
id := listbox1.Items.Strings[i];
if listbox2.Items.IndexOf(id) = -1 then
begin
st := tSortTable.Create;
st.Value := id;
st.Count := 1;
listbox2.Items.AddObject(id, st);
end
else
TSortTable(listbox2.Items.Objects[listbox2.items.IndexOf(id)]).Count :=
TSortTable(listbox2.Items.Objects[listbox2.items.IndexOf(id)]).Count + 1;
end; for i := 0 to listbox2.Items.Count - 1 do
begin
Listbox2.Items.Strings[i] := TSortTable(Listbox2.Items.Objects[i]).Value +
'|' + inttostr(TSortTable(Listbox2.Items.Objects[i]).Count);
TSortTable(Listbox2.Items.Objects[i]).free;
end;
listbox2.Sorted:=true;
listbox2.items.endupdate;
d := GetTickCount - d;
Label2.caption := 'Time:' + Inttostr(d);
end;组件用到
Button1: TButton;
Memo1: TMemo;
Label1: TLabel;
ListBox1: TListBox;
Button2: TButton;
ListBox2: TListBox;
Label2: TLabel;
Button3: TButton;
var
tls : Tstrings;
i : integer;
begin
listbox1.items.clear;
listbox1.items.beginUpdate;
tls := tstringList.create;
for i := 0 to 10000 do
tls.Add(inttostr(Random(i)));
listbox1.Items.Assign(tls);
tls.free; listbox1.Sorted := true;
listbox1.items.endUpdate;
end;procedure TForm1.Button3Click(Sender: TObject);
var
i, c, n : Integer;
Tls:TStrings;
st : TSortTable;
id : string;
b : string;
d : dword;
begin
d := GetTickCount;
Tls := Tstringlist.Create;
Tls.Assign(Listbox1.Items);
listbox2.items.clear;
listbox2.items.beginUpdate;
b := ''; //对比项目
n := 0; //索引位置
c := 0; //记数 for i := 0 to Tls.Count - 1 do
begin
id := Tls.Strings[i];
if id = b then //对比旧数据
c := c + 1; //如果相同则记数加一
if id <> b then //如果不相同则建立新的统计列
begin
Inc(N,1); //增加索引位置
st := tSortTable.Create;
st.Value := id;
st.Count := 1; //初始记数1
listbox2.Items.AddObject(id, st);
if c > 1 then
TSortTable(Listbox2.Items.Objects[n - 2]).Count := c; //修改上一列的总数
c := 1;
b := id;
end;
end;
TSortTable(ListBox2.Items.Objects[n-1]).count :=c; //修改最后列总数
Tls.Free; for i := 0 to listbox2.Items.Count - 1 do
begin //这里是列出项目,并加上数量
Listbox2.Items.Strings[i] := TSortTable(Listbox2.Items.Objects[i]).Value +
'|' + inttostr(TSortTable(Listbox2.Items.Objects[i]).Count);
TSortTable(Listbox2.Items.Objects[i]).free;
end;
listbox2.Sorted := true;
listbox2.items.endupdate;
d := GetTickCount - d;
Label2.caption := 'Time:' + Inttostr(d);
end;
排序+一次遍历
避免过多的内存拷贝,不使用Tstrings或者是listbox 这些额外的开销,直接用数组进行处理。
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, DB, ADODB;type
TForm1 = class(TForm)
Button1: TButton;
ADOTable1: TADOTable;
Button2: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
sl: TStringList;
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
Randomize;
sl.Clear;
for i := 1 to 10000 do
sl.Add(IntToStr(random(10001)));
Application.MessageBox('Finished.', 'hint', MB_ICONINFORMATION);
end;procedure TForm1.FormCreate(Sender: TObject);
begin
sl := TStringList.Create;
end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
sl.Free;
end;procedure TForm1.Button2Click(Sender: TObject);
var
dblBeginTime, dblEndTime: TTime;
iCount, i: Integer;
sTemp: String;
slTemp: TStringList;
begin
sTemp := '';
iCount := 0; slTemp := TStringList.Create;
try
dblBeginTime := Time;
sl.Sort;
for i := (10000 - 1) downto 0 do
if (sTemp <> sl.Strings[i]) then
begin
if ((i + 1) < 10000) then slTemp.Add(sTemp + ':' + IntToStr(iCount)); sTemp := sl.Strings[i];
iCount := 1;
end
else
Inc(iCount);
slTemp.Add(sTemp + ':' + IntToStr(iCount));
dblEndTime := Time;
Application.MessageBox(PChar('Time Used:'#13#10 +
TimeToStr(dblEndTime - dblBeginTime)), 'Hint', MB_ICONINFORMATION);
//毫秒级的时间,呵呵,(dblEndTime - dblBeginTime)的Double值是 1.2E-6 左右 Memo1.Lines.Assign(slTemp);
finally
slTemp.Free;
end;
end;end.