マルチマップがあり、その中のすべての一意のキーをベクターに格納したいと思います。
multimap<char,int> mymm;
multimap<char,int>::iterator it;
char c;
mymm.insert(pair<char,int>('x',50));
mymm.insert(pair<char,int>('y',100));
mymm.insert(pair<char,int>('y',150));
mymm.insert(pair<char,int>('y',200));
mymm.insert(pair<char,int>('z',250));
mymm.insert(pair<char,int>('z',300));
これどうやってするの?キーを持つ要素の数を数える方法はありますが、マルチマップ内の一意のキーの数を数える方法はありません。
追加:一意とは、マルチマップ内のすべてのキーを1回意味します-繰り返したり、マルチマップ内で1回発生したりできます。
したがって、ここでの一意キーは-x、yおよびz
私はこれを試しました、そしてそれはうまくいきました
for( multimap<char,int>::iterator it = mymm.begin(), end = mymm.end(); it != end; it = mymm.upper_bound(it->first))
{
cout << it->first << ' ' << it->second << endl;
}
std::multimap<>
のエントリは暗黙的にソートされ、それらを反復処理するときにソートされた順序で出力されるため、これにはstd::unique_copy
アルゴリズムを使用できます。
#include <iostream>
#include <map>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
/* ...Your existing code... */
/* Create vector of deduplicated entries: */
vector<pair<char,int>> keys_dedup;
unique_copy(begin(mymm),
end(mymm),
back_inserter(keys_dedup),
[](const pair<char,int> &entry1,
const pair<char,int> &entry2) {
return (entry1.first == entry2.first);
}
);
/* Print unique keys, just to confirm. */
for (const auto &entry : keys_dedup)
cout << entry.first << '\n';
cout.flush();
return 0;
}
これによって追加される追加の作業は、マルチマップのエントリ数に比例しますが、重複排除にstd::set
またはJeevaのアプローチを使用すると、両方ともO(n log n)の計算ステップが追加されます。
備考:私が使用するラムダ式はC++ 11を想定しています。これをC++ 03用に書き直すことができます。
mymm
のすべての要素を反復処理し、it->first
をset<char>
に格納します。
最も簡単な方法は、multimapのキーをunordered_setに配置することです。
unordered_multimap<string, string> m;
//insert data in multimap
unordered_set<string> s; //set to store the unique keys
for(auto it = m.begin(); it != m.end(); it++){
if(s.find(it->first) == s.end()){
s.insert(it->first);
auto its = m.equal_range(it->first);
for(auto itr=its.first;itr!=its.second;itr++){
cout<<itr->second<<" ";
}
}
}
unique
が、multimap
に含まれているキーを1回だけ意味する場合、このようなことができると思います。
1)マップ内のすべてのキーのソートされたlist
を作成します
2)リストを繰り返し処理し、一意のキーを見つけます。ソートされたコンテナ内ですべての複製が互いに近くにあるため、簡単です。
すべてのキーだけが必要な場合-Donotaloが提案したようにstd::set
を使用します
他のオプションは、それらをベクトルに挿入してから、std::sort
とstd::unique
を使用することです。
template<typename Container> static
std::vector<typename Container::key_type> unique_keys(Container A)
{
using ValueType = typename Container::key_type;
std::vector<ValueType> v;
for(auto ele : A)
{
v.Push_back(ele.first);
}
std::sort(v.begin(), v.end());
auto it = std::unique(v.begin(), v.end());
v.resize(distance(v.begin(),it));
return v;
}
これはO(N)で実行できます。ここで、Nはマップのサイズです。キーには、順序演算子は必要ありません。
template<typename Container>
std::vector<typename Container::key_type> UniqueKeys (const Container &A)
{
std::vector<typename Container::key_type> v;
auto prevIter = A.begin ();
for (auto iter = A.begin (); iter != A.end(); ++iter)
{
if (prevIter->first == iter->first)
continue;
v.Push_back (prevIter->first);
prevIter = iter;
}
if (prevIter != A.end ())
v.Push_back (prevIter->first);
return v;
}