2011-06-08 63 views
10

嗨,我是使用Delphi和我有这个项的StringList:计数项目频

45 
A15 
015 
A15 
A15 
45 

我要处理它,使将有 的每个元素的出现次数第二的StringList:

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

我该怎么用Delphi来做到这一点?

+0

我希望我有这么酷的功课,当我还是个孩子。 这是为了好玩。 – 2011-06-08 17:17:31

回答

10

你可以使用字典:

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; 

唯一的问题可能是在结果出现的顺序完全是随机的,并在哈希表的内部工作dependes。

感谢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. 
+1

@downvoter:你能解释一下你的理由吗?没有理由的下调无助于任何人,也不是很公平,恕我直言。 – jpfollenius 2011-06-08 10:44:45

+0

@Smasher - 我是downvoter,因为TD200在D2009中有一些问题。但我希望OP能够更新它,所以我编辑了你的答案以便收回。当然这是一个好的和快速的解决方案,但是正如我记得在D2009中向TDictionary添加项目花了很长时间没有更新。 – 2011-06-08 10:51:20

+0

@smasher。 谢谢你的帮助。我无法找到字典组件! 如何在Delphi 2009中使用此功能? – 2011-06-08 11:23:06

3

因为我没有德尔福截至目前已安装的I编码这个在我的头上。让我知道它是如何为你工作的。 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; 
3
  1. 排序原始列表,

    list1.sort; 
    
  2. 创建一个新的列表

    list2:=TStringList.Create; 
    
  3. 遍历排序列表来算每一个不同的项目 并存储一个在结果列表的对象字段中计数(或者如果你不使用它,只是类型将count存入指针并将其作为对象存储)。

    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])+']';