2012-10-08 99 views
1

我需要添加,存儲和刪除一些對象,例如, Person - Hobby。任何人都可以有好幾種愛好,而且幾個人可以擁有相同的愛好。所以,multimap是一個好的容器,對吧?C++找到並擦除multimap元素

添加一對之前,我需要知道,如果它尚未添加。正如我所看到的here沒有標準的類方法可以知道,如果具體的例如MM中存在Peter-Football。因此,我寫了一個方法,返回一個正整數(等於mm.begin()和pair迭代器之間的距離),如果這個對存在的話,返回-1

然後我需要刪除一些對。我打電話給我的find方法,返回一些正整數。我打電話給myMultiMap.erase(pairIndex);,但由於某種原因這對貨幣沒有被刪除。這是我的問題。顯然erase方法需要iterator,而不是int。問題是:如何將整數轉換爲迭代器?

謝謝!

更新: 我已經試過這c.begin() + int_value但得到了一個錯誤error: no match for ‘operator+’在這條線....

+0

您自定義的'find'方法可能會使用迭代器來判斷項目是否存在;只要使用該迭代器,如果它被發現。 – tmpearce

+0

@tmpearce如果我的函數會返回一個迭代器,我怎麼知道,如果這對沒有退出? – Kolyunya

+2

不會'std :: set >'是一個更合適的容器嗎? –

回答

3

不,我喜歡你的方法,但如果int是有問題begin()和迭代器之間的距離,你可以使用

c.begin() + int_value 

std::advance(c.begin(), int_value) 

得到ŧ他迭代器。對於不是隨機訪問迭代器的迭代器需要第二個版本。爲了您的個人理智(以及程序的速度),我建議您以某種形式直接返回迭代器。

有很多可能的接口來解決這種或那種方式。我會叫什麼 「舊的C辦法」 將通過出參數返回:

bool find_stuff(stuff, container::iterator* out_iter) { 
... 
if(found && out_iter) 
    *out_iter = found_iter; 
return found; 
} 

使用它:

container::iterator the_iter; 
if(find_stuff(the_stuff, &the_iter)) ... 

if(find_stuff(the_stuff, 0)) // if you don't need the iterator 

這不是地道的C++,但萊納斯會很高興。

第二種可能的和理論上的聲音版本使用類似boost::optional的東西來返回值。通過這種方式,您可以返回某個值或不返回。

boost::optional<container::iterator> find_stuff(stuff) { 
... 
if(found && out_iter) 
    return found_iter; 
return boost::none; 
} 

用途:

boost::optional<container::iterator> found = find_stuff(the_stuff); 
if(found) { 
    do something with *found, which is the iterator. 
} 

if(find_stuff(the_stuff)) ... 

三可能的解決方案會去的std::set::insert方式,即。返回一對由標誌和值:

std::pair<bool, container::iterator> find_stuff(stuff) { 
... 
return std::make_pair(found, found_iter); 
} 

用途:

std::pair<bool, container::iterator> found = find_stuff(the_stuff); 
if(found.first) ... 
+0

我得到一個錯誤'錯誤:不匹配'運營商+'在線'c.begin()+ int_value' ....我做錯了什麼? – Kolyunya

+0

@Kolyunya:你的迭代器不是隨機存取的。 – jpalecek

2

考慮改變你的mulitmap<Person,Hoobby>set<pair<Person,Hobby> > - 那麼,你會不會有你現在有問題。或考慮更改爲map<Person, set<Hobby> >。這兩個選項都不允許插入重複對。

+0

我需要找到一個具體的人的所有愛好。地圖將允許更快地執行它,因爲它存儲排序的值,對嗎? – Kolyunya

+0

我更新了我的回覆。第二個選項是'map >' - 這樣你就可以快速訪問Person的興趣愛好。 – PiotrNycz

+0

謝謝你的建議! – Kolyunya

1

使用2套(不是多套)一個用於業餘愛好,一個用於個人,這兩個用作過濾器,因此您不會兩次(或hobbie)添加同一個人。這些集合上的插入操作爲插入的元素提供迭代器(如果已插入元素,則爲元素的「正確」迭代器)。從插入到hobbies_set和person_set中獲得的兩個迭代器現在用作多圖中的鍵和值

對於關係而不是multi_map使用第三個集(而不是multi_set),可能會帶來不需要檢查在插入關係之前,如果它已經在那裏,它不會再被添加,如果它不在那裏,它將被添加。在這方面,它會返回一個迭代和布爾(告訴如果它是媒體鏈接存在,或者如果它加入)

數據結構:

typedef std::set<Hobbie> Hobbies; 
typedef std::set<Person> Persons; 
typedef std::pair<Hobbies::iterator,bool> HobbiesInsertRes; 
typedef std::pair<Persons::iterator,bool> PersonsInsertRes; 
struct Relation { 
    Hobbies::iterator hobbieIter; 
    Persons::iterator personIter; 
    // needed operator<(left for the as an exercies for the reader); 
}; 
typedef set<Relation> Relations; 

Hobbies hobbies; 
Persons persons; 
Relations relations; 

插入:

HobbiesInsertRes hres = hobbies.insert(Hobbie("foo")); 
PersonsInsertRes pres = persons.insert(Person("bar")); 
relations.insert(Relation(hres.first, pres.first)); 
// adds the relation if does not exists, if it allready did exist, well you only paid the same amount of time that you would have if you would to do a check first. 

查找:

// for a concrete Person-Hobbie lookup use 
relations.find(Relation(Hobbie("foo"),Person("Bar"))); 

// to find all Hobbies of Person X you will need to do some work. 
// the easy way, iterate all elements of relations 
std::vector<Hobbie> hobbiesOfX; 
Persons::iterator personX = persons.find(Person("bar")); 
std::for_each(relations.begin(), relations.end(), [&hobbiesOfBar, personX](Relation r){ 
    if(r.personIter = personX) 
    hobbiesOfX.push_back(r.hobbieIter); 
}); 

// other way to lookup all hobbies of person X 
Persons::iterator personX = persons.find(Person("bar")); 
relations.lower_bound(Relation(personX,Hobbies.begin()); 
relations.upper_bound(Relation(personX,Hobbies.end()); 
// this needs operator< on Relation to be implemented in a way that does ordering on Person first, Hobbie second. 
+0

然後,我需要找到一個具體的人的所有愛好。 M-Map將允許更快地完成它,因爲它存儲排序的值,對嗎? – Kolyunya

+0

這兩個映射的集合僅在鍵值上排序而不是值 –