StringListに、
A02
B01
A15
A02
A09
・・・・・・
と、3列でたくさんの種類のものが何万行もあるのですが、それぞれの種類の数をShowMessageで、
A02は158個
A09は84個
A15は95個
・・・・・・
と表示させたいのです。できる限りたくさんの変数を使わない方法がいいのですが。
変数3個でやってみました。
もっと少なくできる人いますかね?
function ListUpStrList(var strList:TStringList):string;
var
i0,i1,count: Integer;
begin
Result:='';
for i0 := 0 to strList.Count - 1 do
if strList.Strings[i0][1]<>'*' then
begin
count:=0;
for i1 := i0+1 to strList.Count - 1 do
if strList.Strings[i0] = strList.Strings[i1] then
begin
strList.Strings[i1]:= '*' + strList.Strings[i1];
inc(Count);
end;
Result:= Result + strList.Strings[i0] + 'は' + IntToStr(count) + '個' + #$D#$A;
strList.Strings[i0]:= '*' + strList.Strings[i0];
end;
for i0 := 0 to strList.Count - 1 do
strList.Strings[i0] := Copy(strList.Strings[i0],2,Length(strList.Strings[i0])-1);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
strList:TStringList;
i:Integer;
begin
strList:=TStringList.Create;
for i := 0 to 100000 do
strList.Add('A' + IntToStr(Random(20)));
ShowMessage(ListUpStrList(strList));
strList.Free;
end;
>それぞれの種類の数をShowMessageで、
ShowMessageで何行表示されるのですか
全データをなんらかの方法で表示するなら
一度ソートしてからの方がいいと思いますが
monaa さんに乗っかりマス
変数2個で
function ListUpStrList(strList:TStringList):string;
var
i0,i1: Integer;
begin
i1 := 0;
Result := '';
strList.Sort;
for i0 := 1 to strList.Count -1 do begin
if strList[i0 - 1] = strList[i0] then begin
Inc(i1);
end
else begin
Result:= Result + strList.Strings[i0-1] + 'は' +
IntToStr(i1) + '個' + #$D#$A;
i1 := 0;
end;
end;
Result:= Result + strList.Strings[strList.Count -1] + 'は' +
IntToStr(i1) + '個' + #$D#$A;
end;
TStringListのソートを使っているから、件数が増えれば遅くなっていきそう
この場合の沢山ってのは、リストに数万個あっても数万個変数誓いたくないってことですかね。
速度重視で。
function CountUniqueString(SL: TStringList): TStringList;
var
i, idx: Integer;
begin
Result := TStringList.Create;
for i := 0 to SL.Count - 1 do begin
if not Result.Find(SL[i], idx) then begin
Result.insertObject(idx, SL[i], Pointer(1));
end else begin
Result.Objects[idx] := Pointer(Integer(Result.Objects[idx]) + 1);
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
sl, r: TStringList;
i: Integer;
t: Cardinal;
begin
r := nil;
sl := TStringList.Create;
Randomize;
try
for I := 0 to 100000 -1 do begin
sl.Add('A' + IntToStr(Random(100)));
end;
//t := TimeGetTime;
r := CountUniqueString(SL);
//t := TimeGetTime - t;
for I := 0 to r.count - 1 do begin
Memo1.Lines.Add(r[i] + ': ' + IntToStr(Integer(r.Objects[i])));
end;
//Memo1.Lines.Add(IntToStr(t));
finally
sl.Free;
r.Free;
end;
end;
ツイート | ![]() |