2012-08-02 47 views
1

我有这样一个场景, 我需要存储的字符串的数和我需要回到前十弦它具有最大计数,要使用哪种数据结构?

例如,

String Count 
--------------------------------- 
String1 10 
String2 9 
String3 8 
. 
. 
. 
String10 1 

我考虑使用散列表来存储字符串和它的计数,但是很难从它中检索前十个字符串,因为我必须再次循环来找到它们。

此处有任何其他建议吗?

回答

3

只需使用一个有序映射像

Map<Integer, List<String>> strings 

,其中的关键是频率值和值与频率出现字符串列表。

然后,循环遍历地图,并通过值列表的内部循环,直到看到10个字符串。那些是最常见的10个之一。


随着额外要求,该算法应该支持更新频率:将字符串添加到像Map<String, Integer>一个地图,关键是字符串和值实际频率(增量,如果你的价值再次看到一个字符串)。 之后将键/值对复制到我上面建议的地图。

+0

+1好主意...... – assylias 2012-08-02 14:53:41

+0

如何在计算字符串时更新这样的结构? (虽然没有明确提及,但通常是用例)。 – ffriend 2012-08-02 15:01:10

+0

让我们来计算字符串出现的频率并将其添加到此地图中,并假设有10个字符串,每个字符串都出现10次,那么此地图将具有像1-字符串1这样的条目.... string10,2-string1 ... string10类似地,它对地图中的所有值都有相同的条目,是否有任何优化的解决方案。 – Lokn 2012-08-02 15:03:04

4

Priority Que。

你可以让一个类来把它:

public class StringHolder{ 
    private String string; 
    private int value; 

    //Compare to and equals methods 
} 

则按照当您插入,很容易获得前10名。

+0

如果字符串已经存在,那么我只需要增加计数,如何找到特定的字符串对象呢? – Lokn 2012-08-02 14:53:24

+0

这将是一个相对缓慢的操作。你将不得不遍历所有查找该String的对象。如果你这样做了很多哈希映射可能会更好。 您必须决定是否希望get top 10变慢,或者如果将数据结构中已有的内容更新得更慢。 – Brinnis 2012-08-02 14:59:57

+1

@Lokn:你可以用一个哈希映射对字符串进行计数,然后使用优先级队列来查找N个频率最高的字符串。这将是2次通过,但渐近运行时间仍将摊销O(n)。 – ffriend 2012-08-02 15:20:24

0

对于喜欢“找到前N的任何任务项目“优先队列是完美的解决方案。请参阅Java的PriorityQueue类。

0

番石榴这将是对这个非常有用的一个HashMultiset。

HashMultiset<String> ms = Hashmultiset.create(); 
ms.add(astring); 
ms.add(astring, times); 


ImmutableMultiset<String> ims = Multisets.copyHighestCountFirst(ms); 

// iterator through the first 10 elements, and they will be your top 10 
// from highest to lowest. 
0

为此,您需要Max Heap数据结构。把它全部放入最大堆,并连续10次(或任何n次)清除。

如果您打算在数据加载到内存后继续重用数据,则可能值得按值而不是堆排序。