我有一个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;
答案 0 :(得分:3)
TDictionary
没有排序保证,因此迭代是唯一的解决方案。
任何必要的性能改进都必须涉及不同的数据结构。
答案 1 :(得分:3)
我没有使用过这个特殊的课程,而是优秀的Delphi Collections 1.1.1。有一个类 TDoubleSortedBidiDictionary ,它有排序的值。
顺便说一句,如果您“存储每个单词的出现次数”,请查看Delphi Collections中的 TBag 。它是MultiSet的Delphi实现。何时使用:此双向字典实现使用两个AVL 树木。如果您关心钥匙,请使用它 和值被排序。
答案 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;