【问题标题】:Count item frequency计数项目频率
【发布时间】:2011-06-08 08:47:11
【问题描述】:

您好,我正在使用 Delphi,我有一个包含这些项目的 StringList:

45
A15
015
A15
A15
45

我想处理它并制作第二个字符串列表 每个元素出现的次数:

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

我怎样才能用 Delphi 做到这一点?

【问题讨论】:

  • 我希望我小时候有这么酷的作业。这是为了好玩。

标签: algorithm delphi delphi-2009


【解决方案1】:

你可以使用字典:

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.

【讨论】:

  • @downvoter:你能解释一下你的理由吗?无缘无故投反对票对任何人都没有帮助,而且恕我直言也不是很公平。
  • @Smasher - 我是反对者,因为 D2009 中的 TDictionary 存在一些问题。但我希望 OP 有更新,所以我已经编辑了你的答案以收回它。当然,这是一个又好又快的解决方案,但我记得在 D2009 中将项目添加到 TDictionary 花了很长时间才更新。
  • @smasher。感谢您的帮助。我找不到字典组件!如何在 Delphi 2009 中使用它?
  • 只需将Generics.Collections 添加到您的使用列表即可。
  • @smasher code 使用 ...,Generics.Collections;类型频率 = TDictionary; try // 计算 Str IN FL 的频率 do // 左侧不能分配开始 if Frequencies.ContainsKey(Str) then //表达式期望 Frequencies[Str]:= Frequencies[Str] + 1 else Frequencies.Add(Str, 1);结尾; // 输出结果到控制台 for Str in Frequencies.Keys do WriteLn (Str + ': ' + IntToStr(Frequencies[Str]));最后是 FreeAndNil(频率);结尾; code我收到很多错误
【解决方案2】:
  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】:

    我在脑海中编写了这个代码,因为我现在还没有安装 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;
    

    【讨论】:

      猜你喜欢
      • 2010-10-27
      • 1970-01-01
      • 1970-01-01
      • 2016-11-08
      • 2022-10-14
      • 2018-05-30
      • 2017-12-03
      • 1970-01-01
      • 2021-06-01
      相关资源
      最近更新 更多