【问题标题】:Reading into collection and retrieving top 5读入集合并检索前 5
【发布时间】:2015-03-03 04:26:42
【问题描述】:

我最近在一次采访中被问到这个问题。从实时提要中读取代码和交易量的应用程序, 例如。 AAPL 1000、TWTR 500、MSFT 500、AAPL 500 ... 因此,AAPL 总交易量 = 1500 等等。 我必须将这些读入一个集合并按数量返回前 5 个。

我曾建议在存储时使用哈希映射,然后排序或使用 Treemap。 还有其他更高效的方法吗?

【问题讨论】:

    标签: collections


    【解决方案1】:

    假设代码和交易量一起存储在某个类 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;
        }
    

    【讨论】:

    • 谢谢,我正在尝试实现这一点。因此,首先我将有一个 hashmap 来存储代码和交易量。如何将这些作为参考存储在优先级队列中?一个简短的伪代码会有所帮助。
    • 存储在优先级队列中的类型必须具有可比性。在这种情况下,仅将卷存储为双精度是不够的。代码信息也必须存储。我们可以使用一个类来封装代码及其交易量的概念。
    • 我已经编辑了我的答案以添加一些示例代码。显然,随着存储代码数量的增加,性能差异越来越明显。这也与必须对所有 n 个条目进行排序而不是总是从堆中提取前五个条目有关。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-05
    • 1970-01-01
    • 2014-10-07
    • 2012-08-11
    • 2011-02-01
    • 1970-01-01
    相关资源
    最近更新 更多