給定multimap<A,B>
M用特定鍵創建M中所有值的vector<B>
的方法是什麼?使用給定鍵填充具有所有多圖值的矢量
例如給出一個multimap如何獲得映射到值123的所有字符串的向量?
答案答案很簡單,從下限→上限循環,但有沒有一個整潔的無循環方法?
給定multimap<A,B>
M用特定鍵創建M中所有值的vector<B>
的方法是什麼?使用給定鍵填充具有所有多圖值的矢量
例如給出一個multimap如何獲得映射到值123的所有字符串的向量?
答案答案很簡單,從下限→上限循環,但有沒有一個整潔的無循環方法?
這裏的方式做到這一點STL風格:
// The following define is needed for select2nd with DinkumWare STL under VC++
#define _HAS_TRADITIONAL_STL 1
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <functional>
#include <map>
#include <iterator>
#include <iostream>
using namespace std;
void main()
{
typedef multimap<string, int> MapType;
MapType m;
vector<int> v;
// Test data
for(int i = 0; i < 10; ++i)
{
m.insert(make_pair("123", i * 2));
m.insert(make_pair("12", i));
}
MapType::iterator i = m.lower_bound("123");
MapType::iterator j = m.upper_bound("123");
transform(i, j, back_inserter(v), select2nd<MapType::value_type>());
copy(v.begin(), v.end(), ostream_iterator<int>(cout, ","));
}
那麼,select2nd的不在VC++ 2008呢? – 2010-04-02 18:45:23
它存在於VC++ 2008附帶的Dinkumware頭文件中,但是它和其他幾個文件位於#ifdef _HAS_TRADITIONAL_STL內#endif – 2010-04-02 19:07:28
您可以通過給它兩個迭代器,像這樣的初始化向量:
std::multimap<std::string, std::string> bar;
...
std::vector<pair<string,string> > foo(bar.lower_bound("123"), bar.upper_bound("123"));
但會給你對的矢量(即與鍵和值兩者)。
另一種選擇是使用std::copy
,它與back_inserter類似,這是隱藏循環的另一種方式,但是與上面相同。
std::copy(bar.lower_bound("123"), bar.upper_bound("123"), std::back_inserter(foo));
這會將元素(如果有)添加到向量foo。
對於只提取值,我想不出任何方式,但循環播放結果,因爲我不知道一個標準的方法來獲得超出範圍的值。
一個問題是,這將創建一個'vector
Gack。你說得對,看起來我正確回答了錯誤的問題。 – 2010-04-02 17:51:37
無論如何你需要一個循環。所有「無循環」方法只是將循環抽象出來。
#include <map>
#include <vector>
#include <algorithm>
#include <ext/functional>
using namespace std;
int main() {
multimap<int, double> mm;
mm.insert(make_pair(1, 2.2));
mm.insert(make_pair(4, 2.6));
mm.insert(make_pair(1, 9.1));
mm.insert(make_pair(1, 3.1));
vector<double> v;
transform(mm.lower_bound(1), mm.upper_bound(1),
back_inserter(v), __gnu_cxx::select2nd<pair<int, double> >());
// note: select2nd is an SGI extension.
for (vector<double>::const_iterator cit = v.begin(); cit != v.end(); ++ cit)
printf("%g, ", *cit); // verify that you've got 2.2, 9.1, 3.1
return 0;
}
當然,他們把它抽象出來,這就是問題的關鍵!我認爲你的asnwer是我正在尋找的那種東西,但是我沒有意識到select2nd是非標準的。它在MSVC++嗎? – 2010-04-02 18:35:58
@John:在MSDN中找不到它。但是很容易寫出一個函子'template
template <class Key, class Val>
vector<Val>& getValues(multimap<Key, Val>& multi, Key& key)
{
typedef multimap<Key, Val>::iterator imm;
static vector<Val> vect;
static struct
{
void operator()(const pair<Key, Val>& p) const
{
vect.push_back(p.second);
}
} Push;
vect.clear();
pair<imm, imm> range = multi.equal_range(key);
for_each(range.first, range.second, Push);
return vect;
}
這是因爲你的'無迴路的要求有點做作。
我喜歡:
template <class Key, class Val>
vector<Val> getValues(multimap<Key, Val>& map, Key& key)
{
vector<Val> result;
typedef multimap<Key, Val>::iterator imm;
pair<imm, imm> range = map.equal_range(key);
for (imm i = range.first; i != range.second; ++i)
result.push_back(i->second);
return result;
}
爲什麼要返回一個引用?爲什麼限制用戶一次只能使用1個鍵? – kennytm 2010-04-02 20:58:44
1.爲什麼不呢? 2.因爲這是OP要求的。 – 2010-04-02 21:30:35
走吧拉姆達
給出:multimap<A,B> M
要求:vector<B>
方法:
std::pair<M::iterator, M::iterator> aRange = M.equal_range('a')
std::vector<B> aVector;
std::transform(aRange.first, aRange.second,std::back_inserter(aVector), [](std::pair<A,B> element){return element.second;});
系統環境:
代碼示例:
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <functional>
#include <iostream>
int main()
{
typedef std::multimap<std::string, int> MapType;
MapType m;
std::vector<int> v;
/// Test data
for(int i = 0; i < 10; ++i)
{
m.insert(std::make_pair("123", i * 2));
m.insert(std::make_pair("12", i));
}
std::pair<MapType::iterator,MapType::iterator> aRange = m.equal_range("123");
std::transform(aRange.first, aRange.second, std::back_inserter(v), [](std::pair<std::string,int> element){return element.second;});
for(auto & elem: v)
{
std::cout << elem << std::endl;
}
return 0;
}
你怎麼會去每一個元素沒有循環? – GManNickG 2010-04-02 18:00:29
因此,這個問題,尋找STL的詭計/魔術(爲我們做循環) – 2010-04-02 18:43:32