Частота подсчета - PullRequest
       7

Частота подсчета

10 голосов
/ 08 июня 2011

Привет, я использую Delphi, и у меня есть StringList с этими элементами:

45
A15
015
A15
A15
45

Я хочу обработать его и создать второй список строк, который будет иметь номер появления каждого элемента:

45 [2]
015 [1]
A15 [3]

Как я могу сделать это с Delphi?

Ответы [ 3 ]

10 голосов
/ 08 июня 2011

Вы можете использовать словарь:

Frequencies := TDictionary <String, Integer>.Create;
try
  // Count frequencies
  for Str in StringList do
    begin
    if Frequencies.ContainsKey (Str) then
      Frequencies [Str] := Frequencies [Str] + 1
    else
      Frequencies.Add (Str, 1);
    end; 

   // Output results to console
   for Str in Frequencies.Keys do
     WriteLn (Str + ': ' + IntToStr (Frequencies [Str]));
finally
  FreeAndNil (Frequencies);
end;

Единственная проблема может заключаться в том, что порядок, в котором отображаются результаты, является абсолютно случайным и зависит от внутренней работы хэш-карты.

Спасибо daemon_x за полный код устройства:

program Project1;

{$APPTYPE CONSOLE}

uses SysUtils, Classes, Generics.Collections;

var Str: String;
    StringList: TStrings;
    Frequencies: TDictionary <String, Integer>;

begin
  StringList := TStringList.Create;

  StringList.Add('45');
  StringList.Add('A15');
  StringList.Add('015');
  StringList.Add('A15');
  StringList.Add('A15');
  StringList.Add('45');

  Frequencies := TDictionary <String, Integer>.Create;

  try
  // Count frequencies
  for Str in StringList do
    begin
      if Frequencies.ContainsKey (Str) then
        Frequencies [Str] := Frequencies [Str] + 1
      else
        Frequencies.Add (Str, 1);
    end;

   // Output results to console
   for Str in Frequencies.Keys do
     WriteLn (Str + ': ' + IntToStr (Frequencies [Str]));

finally
  StringList.Free;
  FreeAndNil(Frequencies);
end;

end.
3 голосов
/ 08 июня 2011
  1. Сортировка исходного списка,

    list1.sort;
    
  2. создать новый список

    list2:=TStringList.Create;
    
  3. перебрать отсортированный список, чтобы подсчитать каждый элемент и сохраните счетчик в поле объектов результирующего списка (или, если вы его еще не используете, просто введите счетчик в указатель и сохраните его как объект).

    previtem:=list1[0];
    count:=1;
    for i:=1 to list1.count-1 do
     begin
      if list1[i]=previtem then 
        inc(count)
      else
       begin
        list2.addObject(previtem,pointer(count));
        previtem:=list1[i];
        count:=1;
       end;
     end;
    list2.addObject(previtem,pointer(count));
    

наконец, повторите итерацию, чтобы добавить счетчик в строку

  for i:=0 to list2.count-1 do
    list2.items[i]:=list2[i]+' ['+inttostr(list2.objects[i])+']';
3 голосов
/ 08 июня 2011

Я запрограммировал это на своей голове, так как сейчас у меня не установлена ​​Delphi. Дайте мне знать, как это работает для вас. Stringlist1 - это оригинальный список с элементами, stringlist2 пуст и будет использоваться для хранения того, что вы хотите.

for i := 0 to stringlist1.Count - 1 do
begin
    if (stringlist2.Values[stringlist1[i]] = '') then
        stringlist2.Values[stringlist1[i]] := '1'
    else
        stringlist2.Values[stringlist1[i]] :=
            IntToStr(StrToInt(stringlist2.Values[stringlist1[i]]) + 1);
end;
...