0

I have created the multimap.

multimap<int, std::vector<string> > mt;.

Also I have inserted the elements to it using:

mt.insert(std::make_pair(threadid, funcname));

How to print the elements in multimap using key and value pair?

pmr
  • 58,701
  • 10
  • 113
  • 156
user2380779
  • 11
  • 1
  • 5

2 Answers2

2

You can overwrite operator<< for vector and multimap. Printing code will be looked easier:

#include <iostream>
#include <map>
#include <vector>
#include <string>

template< class T >
std::ostream & operator << ( std::ostream & os, const std::vector< T > & v ) {
    for ( const auto & i : v ) {
        os << i << std::endl;
    }
    return os;
}

template< class K, class V >
std::ostream & operator << ( std::ostream & os, const std::multimap< K, V > & m ) {
    for ( const auto & i : m ) {
        os << i.first << " : " << std::endl;
        os << i.second << std::endl;
    }
    return os;
}

int main() {
    std::multimap<int, std::vector< std::string > > m;

    m.insert(std::make_pair( 1, std::vector< std::string >( {"one", "two", "three" } ) ) );
    m.insert(std::make_pair( 10, std::vector< std::string >( {"ten", "twenty", "thirty" } ) ) );
    m.insert(std::make_pair( 42, std::vector< std::string >( {"foutry", "two" } ) ) );

    std::cout << m;
}

http://ideone.com/LKDPtX

If you don't want to overwrite operator << (I'm wondering why...) you can do it in place:

int main() {
    std::multimap<int, std::vector< std::string > > m;

    m.insert(std::make_pair( 1, std::vector< std::string >( {"one", "two", "three" } ) ) );
    m.insert(std::make_pair( 10, std::vector< std::string >( {"ten", "twenty", "thirty" } ) ) );
    m.insert(std::make_pair( 42, std::vector< std::string >( {"foutry", "two" } ) ) );

    for ( const auto & i : m ) {
        std::cout << i.first << " : " << std::endl;
        for ( const auto & i_v : i.second ) {
            std::cout << i_v << std::endl;
        }
    }
}

At the last, if you can't use C++11 (I'm also wondering why...) you can change code like this:

int main() {
    typedef std::vector< std::string > strings_t;
    typedef std::multimap<int, strings_t > map_t;
    map_t m;

    {
        strings_t v;
        v.push_back( "one" ); v.push_back( "two" ); v.push_back( "three" );
        m.insert( std::make_pair( 1, v ) );
    }
    {
        strings_t v;
        v.push_back( "ten" ); v.push_back( "twenty" ); v.push_back( "thirty" );
        m.insert( std::make_pair( 10, v ) );
    }
    {
        strings_t v;
        v.push_back( "foutry" ); v.push_back( "two" );
        m.insert( std::make_pair( 42, v ) );
    }

    for ( map_t::const_iterator i = m.begin(), e = m.end(); i != e; ++i ) {
        std::cout << i->first << " : " << std::endl;
        for ( strings_t::const_iterator i_v = i->second.begin(), e_v = i->second.end(); i_v != e_v; ++i_v ) {
            std::cout << (*i_v) << std::endl;
        }
    }
}

http://ideone.com/S80nLj

borisbn
  • 4,988
  • 25
  • 42
  • Is there any other method other than overwriting the operator < – user2380779 May 14 '13 at 10:42
  • Yes, it is. Pull out code from operator << and insert it instead of `std::cout << m;` – borisbn May 14 '13 at 11:00
  • I didnt understand what you are saying. can you please make it clear – user2380779 May 14 '13 at 11:13
  • I edited an answer. If you can't use C++11, I can do it once more )) – borisbn May 14 '13 at 11:21
  • It is giving error.a function definition is not allowed here befor ':' token for the line for ( const auto & i : m ) { – user2380779 May 14 '13 at 11:30
  • What's with all the unneccessary stream flushes? – Christian Rau May 14 '13 at 11:50
  • And for the C++98 version a simple `std::copy(i->second.begin(), i->second.end(), std::ostream_iterator(std::cout, "\n"));` might be more concise and streamlined than the inner `for` loop. – Christian Rau May 14 '13 at 11:54
  • @ChristianRau I don't think, that OP must think about optimization here. Isn't it ? – borisbn May 14 '13 at 12:06
  • @borisbn In which way is this an otpimization. It is just clearer, more concise and more streamlined. At what point did I say anything about (performance) optimization (they'll be more or less equally efficient, anyway). – Christian Rau May 14 '13 at 12:07
  • @ChristianRau you told about "unneccessary stream flushes" and I thought you wanted to avoid them for optimization. The other... maybe I'm too conservative, but I like `for` instead of `copy` + `ostream_iterator`. It's easy to modify cycles afterwards – borisbn May 14 '13 at 12:12
  • @borisbn Ah yes, the flushes, already forgot about those. Well yeah, that could be considered an optimization, but it's not a *premature optimization* because it doesn't bring any complexity to do it the right way in the first place, even more so I'd say `'\n'` is much clearer than `std::endl` anyway (though this might again be our indeed diverging views on conciseness and clarity). In fact *not* doing this the correct way right from the start would be a *premature pessimization*. It is just bad practice taught to many people and is as hard to get right as it is easy to learn wrong... – Christian Rau May 14 '13 at 12:21
  • ...which is the reason to teach others correctly when possible. And even more than an optimization it is also conceptually wrong. You just don't need to flush the stream there (though there are certain situation when you really want this) and you would in no way have the idea to do so, if not somebody had told you long ago that *"`std::endl` means newline"*. Had I told you *"you need to flush the stream after each newline"* you would wonder *why*, but not only because you fear the possible perfomance loss, but just out of the inherent curiosity to know why you should do something unneccessary. – Christian Rau May 14 '13 at 12:24
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/29917/discussion-between-borisbn-and-christian-rau) – borisbn May 14 '13 at 12:52
1

You can use below way.

#include <map>
#include <vector>
#include <string>
#include <iostream>
using namespace std;

int main()
{
multimap<int, std::vector<string> > mt;
vector<string> v;
v.push_back("one");
v.push_back("two");

mt.insert(pair<int, vector<string> >(1, v));

multimap<int, std::vector<string> > ::iterator it = mt.find(1);

if(it != mt.end())
{
    for(size_t i = 0; i < (it->second).size(); i++)
       cout<<(it->second)[i]<<endl;
}

}

Output:

one
two

EDIT:

Replace cout line with below line

printf("%s\n", (it->second)[i].c_str());
bjskishore123
  • 6,144
  • 9
  • 44
  • 66