StringListについて


川嶋  2008-09-04 04:36:55  No: 31804

StringListに、
A02
B01
A15
A02
A09
・・・・・・
と、3列でたくさんの種類のものが何万行もあるのですが、それぞれの種類の数をShowMessageで、
A02は158個
A09は84個
A15は95個
・・・・・・
と表示させたいのです。できる限りたくさんの変数を使わない方法がいいのですが。


monaa  2008-09-04 05:34:33  No: 31805

変数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;


TS  2008-09-04 06:52:31  No: 31806

>それぞれの種類の数をShowMessageで、
ShowMessageで何行表示されるのですか
全データをなんらかの方法で表示するなら
一度ソートしてからの方がいいと思いますが


ofZ  2008-09-04 07:23:16  No: 31807

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のソートを使っているから、件数が増えれば遅くなっていきそう


fan  2008-09-04 18:14:08  No: 31808

この場合の沢山ってのは、リストに数万個あっても数万個変数誓いたくないってことですかね。

速度重視で。

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;


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加