簡體   English   中英

使用標准C ++庫向量作為基礎實現來創建Set模板類

[英]create a Set template class using the Standard C++ Library vector as an underlying implementation

我剛剛閱讀了有關模板和迭代器的一章,但這仍然很難理解。 基本上,我想創建一個Set模板類,該模板類僅接受您放入其中的每種類型的對象中的一種,使用矢量來實現。

問題是,我不知道如何在Set類中編寫插入函數,而在嵌套的迭代器類中編寫構造函數。 另外,我提供的大多數功能都是本文章節中的示例,我什至不知道它們是否是必要的,或者我做對了。 評論? 因為這是非常令人困惑的。 這是我的代碼:

//testSetClass.cpp

#include <iostream>
#include <vector>
using namespace std;

/****************************CLASS DEFINITION*********************************/

// -----------------------------------------
 //         SET
 // -----------------------------------------
template <class T>
class Set
{
    vector<T> theSet;
public:
    Set() {}
    Set(const Set& s): theSet(s.theSet){} //copy constructor
    ~Set(){ theSet.clear(); }

    void insert(T t) 
    {
        //insert in orderly fashion? as set class does too
        //also, how do i check for duplicates?
        theSet.push_back(t);
    }

    //nested iterator class: that supports the begin() and end() sentinel
    class iterator; //declaration
    friend class iterator;
    class iterator //definition
    {
        Set<T>& s;
        int index;
    public:
        iterator(const Set<T>& ss): s(ss), index(0){}
        //to create the "end sentinel" operator:
        iterator(Set<T>& ss,bool):s(ss){} //???

        T operator*() {return s.theSet.at(index);} //is this right?

        T operator++() //prefix form
        {
            return ++s.theSet.at(index);
        }
        T operator++(int) //postfix form
        {
            return s.theSet.at(index)++;
        }
        bool operator!=(const iterator& ri)const {return index!=ri.index;}
    };

    //iterators begin() and end()
    iterator begin()const { return iterator (*this); }
    //create the end sentinel:
    iterator end() { return iterator (*this,true); } //why?
};


/*************************************END OF CLASS DEFINITIONS*********************************/


/* *****************************************************************************
 *  MAIN 
 * *****************************************************************************
 *  
 *  REMARKS:
 *     to test that the class works correctly.
 * *****************************************************************************/

int main (int argv, char const *argc[])
{
    Set<int> other;


    for(int i = 0; i<10; ++i)
        other.insert(i);

    for(Set<int>::iterator start = other.begin(); start != other.end(); start++)
        cout<<*start<<endl;

    cout << "\n\nProgram ends successfully!" <<endl;
}

使用std::vector<T>::iterator作為迭代器。 和你的const_iterator類似。

要查找,請使用std::equal_range 如果first==second ,則返回end()

要插入,找到。 如果已經存在,請停止。 如果不存在,請插入。 插入它的惰性方法是后推然后排序。 首先用懶惰的方式做。

完成上述操作后,就可以使用Set<T> 使用一堆數據針對std::set<T>對其進行測試。 編寫一堆單元測試,以確保此Set<T>在重復,排序,查找等方面與std::set<T>相同。


現在,使您的Set<T>更有效。 用對lower_bound<的調用替換該Find ,然后將元素插入應該位於的位置,而不是insert-then-sort。 (可以,這對您沒有任何意義;在閱讀本書之前先獲取有效的Set ,然后花一些時間對其進行包裝)。

或者,創建一個惰性排序的Set<T> ,它盲目追加,並且在插入時很少按指數排序。 在讀取時,它要么進行排序,要么通過二進制搜索檢查排序的部分,並通過線性搜索檢查其余的(小)部分。 或類似的東西。

另一個改進是像上面那樣編寫一個手動iterator 一個不像std::vector迭代器那樣容易失效的函數。 這是...很難正確。

但是,只要有正確性,就可以提高效率。

//此外,如何檢查重復項?

隨着theSet.find() ....

iterator(Set&ss,bool):s(ss){} // ???

那是行不通的。 許多選項,最簡單的方法是將index設置為s.theSet.size()以便現有的!=可以使用。

T運算符*(){返回s.theSet.at(index);} //對嗎?

不,...您需要向vector的元素返回T&而不是副本

運算符++ /運算符++(int)

您需要增加迭代器(即index ),而不要增加迭代器的地址,並應返回*this (返回類型為iterator& )。 研究一些迭代器實現。

迭代器end(){返回迭代器(* this,true); } //為什么?

為什么呢 無論如何,理想情況下,您將提供返回const_iteratorbegin()end() const版本(這非常類似於iterator但只公開const T& ),以及返回iterator s的非const版本:結合使用iterator begin() const將這兩個想法混合在一起。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM