using a key for a set of data

hello everyone,
I would like to use container for defining my data. actually in my algorithm each set of data ( contains more than one data) has a key . I would like to know that can I define it like : map< key, set<int>>
I mean for each key I define a set. if I can not do this, how I can do it with container.
thanks in advance
regards
Yes that will work.
For fun. Here is a example I made.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <set>
#include <map>


typedef std::map<char, std::set<int>> aMap;

void printSet(const std::set<int> &s);
void printMap(const aMap &m);

using namespace std;


int main() {

    // make a map from typdef
    aMap myMap;

    // make the set to insert //
    set<int> aSet = {1, 2, 3};
    // make the key by type and value //
    char a = 'a';

    // create a pair that matches typedef with created values
    std::pair<char, set<int>> pair1(a, aSet);

    // insert into map
    myMap.insert(pair1);

    // loop over map
    printMap(myMap);

    return 0;


}

void printMap(const aMap &m) {
    for (auto const &var : m) {
        // get data
        char tempChar = var.first;
        set<int> tempSet = var.second;

        // print key
        cout << tempChar << endl;
        printSet(tempSet);

    }
}

void printSet(const set<int> &s) {
    for (auto const &x : s) {
            cout << x << endl;
        }
}



a
1
2
3
Last edited on
thank u so much for your answer. however, I get error when I run Bdanielz's code. may I know what is problem
regards
What error do you get?
What compiler do you use?
I use g++ compiler and I have gotten this :
/usr/lib/gcc/x86_64-pc-cygwin/4.9.3/../../../../lib/libcygwin.a(libcmain.o): In
function `main':
/usr/src/debug/cygwin-2.3.1-1/winsup/cygwin/lib/libcmain.c:39: undefined referen
ce to `WinMain'
/usr/src/debug/cygwin-2.3.1-1/winsup/cygwin/lib/libcmain.c:39:(.text.startup+0x7
f): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `WinMain
Try this to add the c++ 11 option

C++11 features are available as part of "mainline" GCC in the trunk of GCC's repository and in GCC 4.3 and later. To enable C++0x support, add the command-line parameter -std=c++0x to your g++ command line. Or, to enable GNU extensions in addition to C++0x extensions, add -std=gnu++0x. GCC 4.7 and later support -std=c++11 and -std=gnu++11 as well.


https://gcc.gnu.org/projects/cxx0x.html
yes, thanx u so much . it works now
I used Bdanielz's code to write what I want. I want that every time this code will be called with a key , first it checks if the key is not available, it just adds this new key and inserts the value to its set. otherwise if key is already exist, it only adds the value to set of this key. in this case, I cannot define name like "pair1" because I do not know key before the program runs .
for example I try this below code in line of 29 of Bdanielz's code. however, I received error:
set<int> bset;
myMap.insert(std::pair<char, set<int> > ('b',bset.insert(6)));
I become thankful to say me how I can solve it
thanks in advance
regards
1
2
3
4
5
bool insert( std::map< std::string, std::set<int> >& map, std::string key, int value )
{
    auto& set = map[key] ; // inserts { key, empty set } if key is not present
    return set.insert(value).second ; // return false if the duplicate value was not inserted
}

http://coliru.stacked-crooked.com/a/2baf6d95d811b13d
thank u so much JLBorges for your code. However, since now I use a simulator based on c++11, I have received error because of using auto as below:
warning: ‘auto’ changes meaning in C++11; please remove it [-Wc++0x-compat]
auto& set=map[key];
error: ISO C++ forbids declaration of ‘set’ with no type [-fpermissive]
auto& set=map[key];
Moreover, I cannot use -std=c++14 command since I do not use g++ directly now. May I know that how I can solve it or what I can write instead of using auto
thanks
regards
1
2
3
4
5
6
bool insert( std::map< std::string, std::set<int> >& map, std::string key, int value )
{
    // auto& set = map[key] ; // inserts { key, empty set } if key is not present
    std::set<int>& set = map[key] ; // inserts { key, empty set } if key is not present
    return set.insert(value).second ; // return false if the duplicate value was not inserted
}
I would use JLBorges code to deal with your required logic.

I noticed that the below will not work
1
2
set<int> bset;
myMap.insert(std::pair<char, set<int> > ('b',bset.insert(6)));


but it would work if would work if it was
1
2
3
  set<int> bset;
    bset.insert(6);
    myMap.insert(std::pair<char, set<int> > ('b',bset));


also there is make_pair for other ways to make pairs besides direct initialization as I am using.
http://en.cppreference.com/w/cpp/utility/pair/make_pair

Last edited on
I really appreciates your guides and helps. it has been very useful for me. however, I face another problem regarding defining iterator for insert function. actually I am modifying one code . at first it looks like :

typedef std::set< IncomingFace > in_container;
typedef in_container::iterator in_iterator;
in_container m_incoming;
Entry::in_iterator
Entry::AddIncoming (Ptr<Face> face)
{ std::pair<in_iterator,bool> ret =
m_incoming.insert (IncomingFace (face));
return ret.first;
}

now I use map instead of set as JIBorges mentioned, so it looks

bool insert(std::map< IncomingFace, std::set<Time> >& map, IncomingFace key, Time value)
{
std::set<Time>& set = map[key] ;
return set.insert(value).second;
}
typedef std::map< IncomingFace, std::set<Time> > in_container;
typedef in_container::iterator in_iterator;
Entry::in_iterator
Entry::AddIncoming (Ptr<Face> face)
{
insert (m_incoming, IncomingFace (face),Simulator::Now ());
std::pair<in_iterator,bool> ret = ????????????? // I do not know how to write
return?????
}
i will become so thankful to know your opinion
thanks
regards
C++98:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <string>
#include <map>
#include <set>

template < typename KEY, typename VALUE > // return bool (true if non-duplicate value was inserted)
bool did_insert( std::map< KEY, std::set<VALUE> >& map, const KEY& key, const VALUE& value )
{ return map[key].insert(value).second ; }

template < typename KEY, typename VALUE > // return iterator to map
typename std::map< KEY, std::set<VALUE> >::iterator
    inserted_at( std::map< KEY, std::set<VALUE> >& map, const KEY& key, const VALUE& value )
{
    typename std::map< KEY, std::set<VALUE> >::iterator map_iter = map.find(key) ;

    if( map_iter == map.end() ) // key was not found, insert { key, empty set }
    {
        std::set<VALUE> empty_set ;
        map_iter = map.insert( std::make_pair( key, empty_set ) ).first ;
    }

    map_iter->second.insert(value) ; // insert value into set

    return map_iter ; // return iterator of map
}

int main()
{
    typedef std::map< std::string, std::set<int> > map_type ;

    map_type my_map ;
    bool b = did_insert( my_map, std::string("abcd"), 23 ) ;
    std::cout << std::boolalpha << b << '\n' ; // true

    b = did_insert( my_map, std::string("efgh"), 23 ) ;
    std::cout << std::boolalpha << b << '\n' ; // true

    b = did_insert( my_map, std::string("abcd"), 23 ) ;
    std::cout << std::boolalpha << b << '\n' ; // false (duplicate value was not inserted)
    
    for( int i = 10 ; i < 15 ; ++i ) did_insert( my_map, std::string("abcd"), i ) ;

    // -----------------------------------------------------------------------

    const map_type::iterator map_iter = inserted_at( my_map, std::string("abcd"), 19 ) ;

    std::cout << map_iter->first << ' ' ; // abcd (key)

    std::set<int>& set = map_iter->second ;
    for( std::set<int>::iterator set_iter = set.begin() ; set_iter != set.end() ; ++set_iter )
        std::cout << *set_iter << ' ' ; // 10 11 12 13 14 19 23 (values)
    std::cout << '\n' ;
}

http://coliru.stacked-crooked.com/a/b37b2c489600407f
thank u so much JLBorges , for your very helpful code. it is very nice.
as I understand, I should only use " inserted_at" function instead of "AddIncoming" function in my code.
thanks
regards
Topic archived. No new replies allowed.