Как перебрать / посчитать для мультикарты <string, string> - PullRequest
6 голосов
/ 15 сентября 2011

Мой класс такой:

class Outgoing
{
    multimap<string,string> outgoing;

    public:
    void makeConnection(string key, string value)
    {
        outgoing.insert(pair<string,string>(key,value));
    }

    void iterate()
    {
        multimap<string, string>::iterator it;
        multimap<string, string>::iterator it2;
        pair<multimap<string,string>::iterator,multimap<string,string>::iterator> ret;
        for (it = outgoing.begin();it != outgoing.end();++it)
        {
            ret = outgoing.equal_range((*it));  ??????
            for (it2=ret.first; it2!=ret.second; ++it2)
            {
                ???????

             }
        }
    }
};

фон:

Я хочу представить график, который может иметь много узлов. Ключ не повторяется, но может иметь несколько значений.

str1  ----> val1
str1  ----> val2
str2 -----> val3

Я хочу знать, как я могу получить количество значений для определенного ключа? например, в приведенном выше вопросе для str1 это будет 2?

Как видите, я попытался что-то сделать после того, как покопался, но тщетно.

Что не так с моим кодом?

спасибо

РЕДАКТИРОВАТЬ ::: после комментария templatetypedef я отредактировал код так:

for (it = outgoing.begin();it != outgoing.end();++it)
{
    cout<< (*it).first << " "<<  outgoing.count((*it).first); 

}

Я могу получить счет, но ключ ("str1") приходит дважды. Поэтому я вижу ответ 2 2 1.

Я был бы очень признателен, если бы кто-нибудь научил меня, как выполнять итерации таким образом, я получил бы только один ключ. Кстати, спасибо, templatetypedef

Ответы [ 2 ]

5 голосов
/ 15 сентября 2011

Для этого можно использовать функцию count, которая возвращает количество записей в multimap с заданным ключом.В вашем примере запись

outgoing.count("str1")

приведет к значению 2.

В C ++ нет способа перебирать только уникальные ключи в multimap.Если вы хотите перебрать только эти ключи, есть два варианта, которые вы можете рассмотреть:

  1. Вы можете перейти с использования multimap< string, string > на map<string, vector<string> >.Таким образом, каждый ключ уникален, и вы можете легко определить, сколько значений связано с каждым ключом, просто взглянув на количество элементов в соответствующем vector.

  2. Вы можетеиметь цикл верхнего уровня для перебора всех ключей, а затем внутренний цикл для пропуска дублирующих ключей.

В качестве примера варианта 2 вы можете попробовать что-то вроде этого:

for (multimap<string, string>::iterator itr = myMap.begin(); itr != myMap.end(); ) {
    /* ... process *itr ... */

    /* Now, go skip to the first entry with a new key. */
    multimap<string, string>::iterator curr = itr;
    while (itr != myMap.end() && itr->first == curr->first)
        ++itr;
}

Надеюсь, это поможет!

2 голосов
/ 17 апреля 2016

Функция equal_range предоставляет пару итераторов, причем первый и последний элементы карты имеют общий ключ.

http://www.cplusplus.com/reference/map/multimap/equal_range/

// multimap::equal_range
#include <iostream>
#include <map>

int main ()
{
  std::multimap<char,int> mymm;

  mymm.insert(std::pair<char,int>('a',10));
  mymm.insert(std::pair<char,int>('b',20));
  mymm.insert(std::pair<char,int>('b',30));
  mymm.insert(std::pair<char,int>('b',40));
  mymm.insert(std::pair<char,int>('c',50));
  mymm.insert(std::pair<char,int>('c',60));
  mymm.insert(std::pair<char,int>('d',60));

  std::cout << "mymm contains:\n";
  for (char ch='a'; ch<='d'; ch++)
  {
    std::pair <std::multimap<char,int>::iterator, std::multimap<char,int>::iterator> ret;
    ret = mymm.equal_range(ch);
    std::cout << ch << " =>";
    for (std::multimap<char,int>::iterator it=ret.first; it!=ret.second; ++it)
      std::cout << ' ' << it->second;
    std::cout << '\n';
  }

  return 0;
}
...