2012-03-23 45 views
5

所以我有一組pairs<string ,string>C++設置搜索對元素?

而且我想用find()搜索一個字符串這將是「第一」的一對,那麼如果我發現字符串中第一個我想回到第二從那個功能。

我現在的嘗試是..

myList::iterator i; 

i = theList.find(make_pair(realName, "*")); 

return i->second; 
+7

你爲什麼不使用'map'?其他注意事項:如果它是'std :: set',爲什麼叫'myList'?你是否爲'std :: pair'創建了一個比較函數?它看起來怎樣? – 2012-03-23 16:56:43

回答

2

您可以使用std::set<std::pair<std::string, std::string> >這個,但你需要一個自定義的 比較對象,是因爲兩人的關係運算符對本兩個元素。這就是說,它好像你實際上應該使用std::map<std::string, std::string>來代替。

+1

我不同意,語義會有很大的不同,特別是無法存儲具有相同「關鍵」的幾個項目。一個'multimap'在語義上可能更接近,但是不能保證這個對的唯一性,這也是可取的。在不知道要求的情況下,你的答案確實是在黑暗中拍攝的...... – 2012-03-23 20:20:21

1

<的定義std::pair實現了字典順序,""是字符串的最小元素。結合我們得到:

typedef std::pair<std::string, std::string> StringPair; 
typedef std::set<StringPair> Set; 

std::string const* find_first(Set const& s, std::string const& key) { 
    Set::const_iterator const it = s.lower_bound(std::make_pair(key, "")); 

    // Check that it actually points to a valid element whose key is of interest. 
    if (it == s.end() or it->first != key) { return 0; } 

    // Yata! 
    return &it->second; 
} 

訣竅是適當地使用lower_bound

返回指向第一個元素的迭代器,該元素的比較值不小於value

  • 如果返回end(),那麼就沒有發現什麼有趣的事。
  • 否則,it->first >= key所以我們擺脫>箱子(沒有興趣到我們)

我想指出,雖然,這只是返回範圍的第一要素。如果你有興趣中的所有元素,嘗試:

typedef std::pair<Set::const_iterator, Set::const_iterator> SetItPair; 

SetItPair equal_range_first(Set const& s, std::string const& key) { 
    StringPair const p = std::make_pair(key, ""); 
    return std::make_pair(s.lower_bound(p), s.upper_bound(p)); 
} 

這將返回全方位節點的s它的第一個元素是等於key。然後你只需要遍歷這個範圍:

for (Set::const_iterator it = range.first; it != range.second; ++it) { 
    // do something 
} 

而且你甚至不擔心的lower_boundupper_bound回報是否結束與否。

  • 如果lower_bound返回end(),然後這樣做upper_bound,並且環路被跳過
  • 如果lower_bound指向的節點對,其it->first > key,然後upper_bound將指向同一節點,並且環路被跳過

這就是範圍的力量:不需要進行特殊檢查,當沒有匹配時,範圍最終爲空,因此循環遍歷它們......被一次性檢查跳過。

+0

如果第二個元素是int,該怎麼辦? – user3522401 2016-02-01 16:32:50

6

C++ 11是否可以接受?

auto it = find_if(theList.begin(), theList.end(), 
    [&](const pair<string, string>& val) -> bool { 
     return val.first == realName; 
    }); 

return it->second; 

還是在C++ 03,首先定義一個函子:

struct MatchFirst 
{ 
     MatchFirst(const string& realName) : realName(realName) {} 

     bool operator()(const pair<string, string>& val) { 
       return val.first == realName; 
     } 

     const string& realName; 
}; 

然後調用它像這樣:

myList::iterator it = find_if(a.begin(), a.end(), MatchFirst(realName)); 
return it->second; 

這將只返回第一個比賽,但是從你的問題,它看起來就是你所期待的。