2014-11-05 69 views
1

因此,我將對象放置在矢量中。我想在添加它們時按順序放下它們。對象的基礎是向量中的字符串。並將它們按順序排列

class myObj { 
    private: 
    string firstName; 
    string lastName; 
    public: 
    string getFirst; 
    string getLast;  
} 

我也有這些對象

vector<myObj> myVect; 
vector<myObj>::iterator myVectit = myVect.begin(); 

的載體,當我添加一個新的對象,我想找到它應該插入之前被放置在載體。我可以通過對象值搜索矢量嗎?這是我的第一次嘗試

void addanObj (myObj & objtoAdd){ 
    int lowwerB = lower_bound(
       myVect.begin().getLast(), myVect.end().getLast(), objtoAdd.getLast() 
       ); 
    int upperB = upper_bound(
       myVect.begin().getLast(), myVect.end().getLast(), objtoAdd.getLast() 
       ); 

從那裏我打算使用lowwerB和上面的B來確定插入條目的位置。我需要做些什麼來實現這個目標,或者什麼是解決這個挑戰的更好方法?

----跟進----

錯誤,我得到當我試圖編譯

error C2440: 'initializing' : cannot convert from 'std::string' to 'int' 
No user-defined-conversion operator available that can perform this conversion, 
or the operator cannot be called 

編譯器突出了LOWER_BOUND和UPPER_BOUND。我猜想它指的是我把

objtoAdd.getLast() 

其中-----更多跟進----------------- 這是接近,但編譯不完全的。我應該期望從lower_bound和upper_bound獲得什麼?它不匹配我定義的迭代器,我不知道我應該期待什麼。

void addMyObj(myObj myObjtoadd) 
    vector< myObj>::iterator tempLB; 
    vector< myObj>::iterator tempUB; 
    myVectit= theDex.begin(); 
    tempLB = lower_bound(
       myVect.begin()->getLast(), myVect.end()->getLast(), myObjtoadd.getLast() 
      ); 
    tempUB = upper_bound(
      myVect.begin()->getLast(), myVect.end()->getLast(), myObjtoadd.getLast() 
      ); 
+1

你有什麼理由使用'vector'嗎?看起來你可能想要一個'std :: map'或'std :: multimap',當你調用'insert'時,它將返回一個指向插入對象的迭代器。它也將保持一切爲你排序。 – druckermanly 2014-11-05 03:12:37

+2

由於沒有邏輯關鍵與價值,我認爲你的意思是設置,而不是地圖。 – chris 2014-11-05 03:16:33

+0

此外,請參閱此處:http://stackoverflow.com/questions/15843525/how-do-you-insert-the-value-in-a-sorted-vector – msandiford 2014-11-05 03:21:41

回答

0

您對std::lower_boundstd::upper_bound的撥打電話不正確。前兩個參數必須是迭代器,它們定義要搜索的元素範圍,返回的值也是迭代器

由於這些算法將容器元素與第三個參數值進行比較,因此您還需要提供正確的operator<函數,用於比較對象的lastNamestd::string。我添加了兩個不同的比較函數,因爲std::lower_boundstd::upper_bound以相反的順序傳遞參數。

我想我在這段代碼中有正確的機器,它應該足夠接近你的想法。

class myObj { 
    private: 
     std::string firstName; 
     std::string lastName; 
    public: 
     std::string getFirst() const { return firstName; } 
     std::string getLast() const { return lastName; } 
}; 

bool operator<(const myObj &obj, const std::string &value) // used by lower_bound() 
{ 
    return obj.getLast() < value; 
} 

bool operator<(const std::string &value, const myObj &obj) // used by upper_bound() 
{ 
    return value < obj.getLast(); 
} 

int main() 
{ 
    std::vector<myObj> myVect; 
    std::vector<myObj>::iterator tempLB, tempUB; 
    myObj objtoAdd; 

    tempLB = std::lower_bound(myVect.begin(), myVect.end(), objtoAdd.getLast()); 
    tempUB = std::upper_bound(myVect.begin(), myVect.end(), objtoAdd.getLast()); 
} 
0

所以這絕對不是最好的選擇。這裏的原因:

矢量大小

默認的Vector開出0的元素,但能力持有一定數量的;說100.添加101st元素後,它必須完全重新創建矢量,複製所有數據,然後刪除舊的內存。如果做得夠好,這種複製可能會變得很昂貴。

插入到載體

這將是更是一個問題。因爲向量是內存與存儲在插入順序的對象只是一個連續的塊,說你有以下:

[xxxxxxxzzzzzzzz   ] 

,如果你想添加「Y」,它屬於X和Z之間的,對不對?這意味着你需要將所有的z移到1以上。但是因爲你正在重複使用同一塊內存,所以你需要一次一個地完成。

[xxxxxxxzzzzzzz z   ] 
[xxxxxxxzzzzzz zz   ] 
[xxxxxxxzzzzz zzz   ] 
... 
[xxxxxxx zzzzzzzz   ] 
[xxxxxxxyzzzzzzzz   ] 

(空格是爲了清晰 - 前值未明確清零)

正如你所看到的,這是很多的步驟,以騰出空間給你的「Y」,而且會很對於大型數據集非常緩慢。

更好的解決方案

正如其他人所說,std::set聽起來像它更適合您的需求。 std::set將自動對所有插入的元素進行排序(使用樹狀數據結構進行快速插入),並允許您在log(n)時間內按姓氏查找特定數據成員。它通過使用bool myObj::operator(const & _myObj) const來了解如何對不同的對象進行排序。如果您簡單地定義此運算符來比較this->lastName < _myObj.lastName,則可以更簡單地將其插入到該集合中。或者,如果您確實想要使用vector:而不是隨意排列它,只需將所有項目添加到該向量中,然後在所有插入完成後執行std::sort對它們進行排序。這也將在n log(n)時間內完成,但由於矢量插入問題,應該比當前方法快得多。

+0

好的事情要考慮效率。但這是一個需要工作的學校項目。下次我會記住這一點。感謝您的輸入! – 2014-11-05 15:10:52

相關問題