哪个是在delphi TDictionary中找到最大值的最佳方法?

时间:2011-05-04 02:21:44

标签: delphi generics dictionary delphi-xe

我有一个TDictionary声明如此TDictionary<String,Integer>,现在我想获得存储在TDictionary中的最大值。我可以迭代TDictionary并比较值,但我想知道存在更好的方法吗? exist any function or maybe the dictionary can be sorted by the values to retrieve the max value stored?

这就是我现在正在做的事情

var
   MyDict       : TDictionary<String,Integer>;
   MaxValue, i  : Integer;
begin
   MyDict:=TDictionary<String,Integer>.Create;
   try    
     MyDict.Add('this',1);
     MyDict.Add('is',7);
     MyDict.Add('a',899);
     MyDict.Add('sample',1000);
     MyDict.Add('finding',12);
     MyDict.Add('the',94);
     MyDict.Add('max',569);
     MyDict.Add('value',991);

     MaxValue:=MyDict.ToArray[0].Value;
     for i in MyDict.Values do
      if i>MaxValue then MaxValue:=i;

     ShowMessage(Format('The max value is %d',[MaxValue]));
   finally
     MyDict.Free;
   end;
end;

4 个答案:

答案 0 :(得分:3)

TDictionary没有排序保证,因此迭代是唯一的解决方案。

任何必要的性能改进都必须涉及不同的数据结构。

答案 1 :(得分:3)

我没有使用过这个特殊的课程,而是优秀的Delphi Collections 1.1.1。有一个类 TDoubleSortedBidiDictionary ,它有排序的值。

  

何时使用:此双向字典实现使用两个AVL   树木。如果您关心钥匙,请使用它   和值被排序。

顺便说一句,如果您“存储每个单词的出现次数”,请查看Delphi Collections中的 TBag 。它是MultiSet的Delphi实现。

答案 2 :(得分:2)

如果主要目的是快速查找字符串并更新计数,

Dictionary是正确的数据结构。通常对于这种算法,您花费更多时间计算单词而不是查找最大值。当循环数百万个单词时,由于更快的查找,它可能意味着比tstringlist有显着的性能优势。

您可以使用Math-unit中的 MaxIntValue(MyDict.ToArray)来获得更优雅的代码,但它仍然是顺序的。如果您发现找到最大值是性能瓶颈,那么您可以考虑备用数据结构。

答案 3 :(得分:2)

您是否要删除商品或减少商品的数量?如果没有,您可以考虑创建一个TDictionary的新后代,您可以在其中覆盖Add()方法并跟踪到目前为止添加的最大项目。下面的代码是伪代码,并不完全正确。 (例如,我认为Add()应该覆盖一个函数,但我把它编码为一个过程)。但它给出了一般的想法。当然,此代码仅跟踪一个项目:最近最近添加的项目。如果您需要列出具有最大计数的所有项目,则可以保留字符串列表而不是fLargestWordSoFar和fLargestCountSoFar。

即使你在添加项目之后增加项目的数量,你也可以扩展下面的代码,以类似于Add()的方式处理它。

type
  MyTDictionary = object(TDictionary) // almost definitely not correct syntax here...
  private
    fLargestCountSoFar: Integer;
    fLargestWordSoFar: String;   
  public
    procedure Add( S: String; I:Integer); override;   
  end;

implementation

procedure MyTDictionary.Add( S: String; I:Integer); 
begin
  if (I > fLargesteCountSoFar) then
  begin
    fLargestCountSoFar := I;
    fLargestWordSoFar  := S;    
  end;
  inherited Add( S, I);
 end;