2016-01-21 70 views
0

我編寫了下面的代碼,用於將唯一值插入數據結構中,從中我可以按排序順序檢索值(在下面的代碼中,我使用了優先級隊列來實現此目的,但是,任何其他數據結構如分類矢量也可以使用)。但是,我發現下面的代碼非常慢,因爲我將100萬個值插入到我的優先級隊列中。是否有人可以幫助我明白,我怎麼能提高如下代碼:將值唯一地插入優先級隊列C++

class unique_queue1 { 
//private: 
public:  
    std::priority_queue<std::pair<vector<int>, double>, vector<std::pair<vector<int>, double> >, CompareClass1 > m_queue; 
    std::set<vector<int> > m_set; 
//public: 
    bool push(const pair<vector<int>, double> & t) { 
     if (m_set.insert(t.first).second) { 
      m_queue.push(t); 
      return true; 
     } 
     return false; 
    } 

    void pop() { 
     assert(!m_queue.empty()); 
     const std::pair<vector<int>, double>& val = front(); 

     std::set<vector<int> >::iterator it = m_set.find(val.first); 
     assert(it != m_set.end()); 

     m_set.erase(it); 
     m_queue.pop(); 
    } 

    const pair<vector<int>, double>& front() const { 
     return m_queue.top(); 
    }  

    bool empty() const{ 
     return m_queue.empty(); 
    } 
}; 
+0

如果您需要'set'那麼你並不需要的優先級隊列。 'set'總是有第一個項目可以輕鬆訪問。你不需要額外的'find'工作來匹配'set'中的第一項,你根本不需要優先級隊列。 – JSF

+0

@JSF我對C++有點新鮮。如果可能的話,我會非常感激,如果你能幫我一點代碼。作爲C++的新手,我無法理解你在說什麼。在我的代碼中,我保持「設置」,以便插入優先級隊列的值(矢量)是唯一的 –

+0

您需要多快?更改'set'來完成整個工作並消除優先級隊列應該使代碼快兩倍。但是如果你需要更多的改進,你需要更加基本的重新設計。爲了使'set'完成整個工作,它必須保存相同的對象,並且具有現在用於優先級隊列的相同比較功能(而不僅僅是大部分對象和默認比較)。 – JSF

回答

2

既然要強制唯一性,你真的只需要設定。現在

#include <vector> 
#include <set> 

using namespace std; 
class unique_queue1 
{ 
public: 
    using value_type = std::pair<vector<int>, double>; 
    std::set<value_type, CompareClass1> m_set; 

    bool push(const value_type& t) { 
     return m_set.insert(t).second; 
    } 

    void pop() { 
     m_set.erase(m_set.begin()); 
    } 

    const value_type& front() const { 
     return *m_set.begin(); 
    } 

    bool empty() const{ 
     return m_set.empty(); 
    } 
}; 

,除非你做的那類你一些額外的魔法,你當然可以只需更換整個事情只用一套...

除此之外,您的介紹文字讀起來就像您實際上首先需要用數據填充容器,並且只有在完全填充數據後,才需要按排序順序獲取唯一條目。

我建議你嘗試一切推到一個載體,然後使用算法std::sortstd::uniquestd::reverse,然後使用pop_back檢索數據。我相當肯定,這會比使用set快得多。

這裏是如何做到這一點的樣子(未經測試):

class unique_queue1 
{ 
public: 
    using value_type = std::pair<vector<int>, double>; 
    std::vector<value_type> values; 

    void push_back(const value_type& t) 
    { 
    return values.push_back(t); 
    } 

    // Must be called between push_back and (pop or front) 
    void prepare() 
    { 
    sort(values.begin(), 
     values.end(), 
     CompareClass1()); // Maybe use lambdas for comparison 
    erase(unique(values.begin(), 
       values.end(), 
       CompareClass2()), // Need a comparator for equality, again, 
            // you might want to use a lambda 
      values.end()); 

    reverse(values.begin(), values.end()); 
    } 

    void pop() 
    { 
    values.pop_back(); 
    } 

    const value_type& front() const 
    { 
    return values.back(); 
    } 

    bool empty() const 
    { 
    return values.empty(); 
    } 
}; 
+0

,但對於設置的解決方案,它給了我一個錯誤:錯誤:沒有匹配函數調用'std :: set ,double>>,CompareClass1> :: insert(const std :: vector &)' return m_set.insert(t.first).second; ^ –

+0

我沒有運行編譯器,只是顯示了一般的想法。我更新了要編譯的代碼(儘管我不知道你的比較在做什麼,所以你可能仍然遇到一些麻煩)。 – Rumburak

+0

恐怕它仍然給我同樣的錯誤...似乎插入不工作。我正在使用gcc-4.9編譯器和C++ 11 –