web-dev-qa-db-ja.com

マルチマップですべての一意のキーを取得するにはどうすればよいですか

マルチマップがあり、その中のすべての一意のキーをベクターに格納したいと思います。

  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回発生したりできます。

したがって、ここでの一意キーは-xyおよびz

19
AJ.

私はこれを試しました、そしてそれはうまくいきました

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;
  }
35
Jeeva

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用に書き直すことができます。

16
jogojapan

mymmのすべての要素を反復処理し、it->firstset<char>に格納します。

7
Donotalo

最も簡単な方法は、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<<" ";
        }
    }
}
2
Gautam Jain

uniqueが、multimapに含まれているキーを1回だけ意味する場合、このようなことができると思います。

1)マップ内のすべてのキーのソートされたlistを作成します

2)リストを繰り返し処理し、一意のキーを見つけます。ソートされたコンテナ内ですべての複製が互いに近くにあるため、簡単です。

すべてのキーだけが必要な場合-Donotaloが提案したようにstd::setを使用します

1
Andrew

他のオプションは、それらをベクトルに挿入してから、std::sortstd::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;
}
0
newandlost

これは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;
}
0
Catriel