我最近在接受采访时被问到这个问题。从实时订阅源读取股票代码和交易量的应用程序, 例如。 AAPL 1000,TWTR 500,MSFT 500,AAPL 500 ...... 所以,AAPL总量= 1500,依此类推。 我必须把它们读成一个集合并按体积返回前5个。
我建议在存储时使用哈希映射,然后排序或使用Treemap。 还有其他更有效的方式吗?
答案 0 :(得分:0)
假设股票代码和交易量一起存储在某个类TickerAndTradeVolume的实例中,您可以引用多个数据结构中包含的对象。
因此,哈希映射可以将股票代码作为关键字,将TickerAndTradeVolume作为值。然后,对TickerAndTradeVolume实例的引用也可以存储在优先级队列中。每次卷更新时都会将实例重新插入PQ。
按卷分列的前n个总是以log(n)摊销的时间复杂度提供,以按交易量维持优先级,这比通过Treemap一次又一次地进行排序的速度渐渐快。
像这样的东西
Map<String, TickerAndTradeVolume> feed;
PriorityQueue<TickerAndTradeVolume> pq;
class TickerAndTradeVolume implements Comparable<TickerAndTradeVolume> {
private String ticker;
private double volume;
TickerAndTradeVolume(String ticker, double volume) {
this.ticker = ticker;
this.volume = volume;
}
void increaseVolumeBy(double volume) {
this.volume += volume;
}
@Override
public int compareTo(TickerAndTradeVolume that) {
return (int) (that.volume - this.volume);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if(obj instanceof String) {
TickerAndTradeVolume that = (TickerAndTradeVolume) obj;
return this.ticker.equals(that.ticker);
}
return false;
}
}
void addOrUpdateStockVolume(TickerAndTradeVolume tt) {
if(!feed.containsKey(tt.ticker)) {
feed.put(tt.ticker, tt);
pq.add(tt);
}
else {
feed.get(tt.ticker).increaseVolumeBy(tt.volume);
// take out and put back in to trigger heap operations
pq.remove(feed.get(tt.ticker));
pq.add(feed.get(tt.ticker));
}
}
List<TickerAndTradeVolume> getTopMaxFive() {
List<TickerAndTradeVolume> topFive = new ArrayList<TickerAndTradeVolume>(5);
int pqSize = pq.size();
for(int i = 0; i < 5 && i < pqSize; i++) {
// poll() takes from the top of the heap
topFive.add(pq.poll());
}
for(TickerAndTradeVolume tt : topFive) {
// put back what we took out
pq.add(tt);
}
return topFive;
}