Author: Howard JohnsonDate: 2022-07-05
Question:I have a mapand my structure is defined as follows.in myMap key is int and value is vector of structure Is it possible to have a map where the key is a string, and the value is an array of structures?
- How to create a map with key and value as structs in C++?
- How can I make a map where the value is an array of structs in C++
- How to create the map Of the vector of structure in c++
- C++: struct pointer in map structure
- What is map () in C?
- How do you create a structure in C?
- Is there a map in C?
- What is the structure of a map in C++?
How to create a map with key and value as structs in C++?
Question:
I'm trying to create a map whose key and value are both structs (stE and stR), so I have something like this:
struct stR{ char* est; char* et; };struct stE{ int num; char* form; char* et; map<stE,stR> s; };
But when I want to insert a new element:
stE e;e.num=1;e.form="a";e.et="b";stE f;f.num=2;f.form="c";f.et="d";stR r;r.est="e";r.et="";e.s.insert(make_pair(f, r));
It gives me an error:
C:\Dev-Cpp\include\c++\3.4.2\bits\stl_function.h In member function `bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = stEstado]':
I can't find what's the problem. Could anyone help me?Thanks in advance.
Solution 1:
When using a map, you need to provide a less-than operator or give it a comparer since it orders the keys automatically.
bool stE::operator< (const stE &);
Solution 2:
You need to provide strict weak ordering comparison, which you can achieve by definingoperator<
for yourstE
or passing a comparator function of functor as a map template parameter.std::map
looks something like this:
template<class Key, class T, class Compare = std::less<Key>, ... > class map;
By default,Compare
is set to useT::operator<(const T&)
, but you can pass your own functor type which implements the logic. This is important if you cannot modify the actual class.
Bear in mind that the map needs to be able to insert default constructedstR
objects, and your current structure has no default constructor, to the pointers will be initialized to random values. This could be an issue further along the line.
Also, your key struct has a map where it is it's own key type. This could cause recursion problems when you try to implement the less-than comparison:
struct stE{ int num; char* form; char* et; map<stE,stR> s; // how do we use this in the comparison?};
Hash Table in C/C++ - A Complete Implementation, A good Hash function to map keys to values; A Hash Table Data Structure that supports insert, search and delete operations. A Data Structure to
Map in C++ with practical examples
An important characteristic of the map collection is that it orders elements by key in ascendingDuration: 19:52
How can I make a map where the value is an array of structs in C++
Question:
I have the following structure.
struct Tourist { string name; string surname; string sex;};
I would like to sort tourists by families.
int getMinRoomsAmount(Tourist touristsList[]) { map<string, Tourist[]> families; for (int i=0; i < 40; i++) { families[touristsList[i].surname] = // to append the array with the tourist } return 0;}
Is it possible to have a map where the key is a string, and the value is an array of structures?And how can I append the array with new entries?
Solution 1:
- Map :You could use a map of string and vector of Tourist -
map<string, std::vector<Tourist> > families;
. - Insertion :For adding a new element to a family, just use
push_back()
method of vector as -families[touristsList[i].surname].push_back(touristsList[i]);
. This statement will simply add the family(Tourist
struct) to the map with key of surname.
Below is a working demo of your program -
#include <iostream>#include<map>#include<vector>struct Tourist { std::string name; std::string surname; std::string sex;};int getMinRoomsAmount(std::vector<Tourist> touristsList) { std::map<std::string, std::vector<Tourist> > families; for (int i=0; i < 3; i++) { // to append the array with the tourist families[touristsList[i].surname].push_back(touristsList[i]); } // iterating over the map and printing the Tourists families-wise for(auto it:families){ std::cout<<"Family "<<it.first<<" : \n"; for(auto family : it.second){ std::cout<<family.name<<" "<<family.surname<<" "<<family.sex<<std::endl; } std::cout<<"\n-------\n"; } return 0;}int main() { // making 3 struct objects just for demo purpose Tourist t1={"a1","b1","m"}; Tourist t2={"a2","b1","f"}; Tourist t3={"a3","b3","m"}; // inserting the objects into vector and then passing it to the function std::vector<Tourist>t={t1,t2,t3}; getMinRoomsAmount(t);}
I have just included 3 Tourist objects for demo purpose. You can modify the code to suit your needs. I have used vectors instead of array because they are more efficient and you can dynamically push/pop as per the user inputs later on if you want to modify the program.
Hope this helps !
Solution 2:
You really want to stay away from arrays, especially when usingstd::map
. Thestd::map
will copy your structure and arrays don't copy well.
Here is the definition of a map with value as an std::vector:
std::map<std::string, std::vector<Tourist>>
Here is how to add to the map:
std::vector<Tourist> database;Tourist t1{"x", "x", "x"};Tourist t2{"y", "y", "y"};Tourist t3{"z", "z", "z"};database.pushback(t1);database.pushback(t2);database.pushback(t3);// Check this out:std::map<std::string, std::vector<Tourist>> visitors;visitor["Italy"] = database;
Solution 3:
Use a map of string→vector<Tourist>
.
Then use the vectors in the normal way, e.g.push_back
.
Map in C++ Standard Template Library (STL), Maps are associative containers that store elements in a mapped fashion. Each element has a key value and a mapped value.
How to create the map Of the vector of structure in c++
Question:
I have a mapstd::map<int, std::vector<Data>>myMap
and my structure is defined as follows.
struct Data { int x; int z; int y; };
in myMap key is int and value is vector of structure and I dont want create the temporary vector or structure while inserting to the map. Is there any idea to achieve it?
Solution 1:
One method is to useemplace
andstd::move
myMap.emplace(key, std::move(myVec));
By usingstd::move
you can construct the vector outside of the map, and then move that vector into the map without any copying.
Solution 2:
You don't need to explicitly initilize values in a map. When you access a key viaoperator[]
that does not exist in the map it will be added with a default initialized value (an emptystd::vector
in your case).
So you can safely do something like
myMap[0].push_back(myInstanceOfData)
even if the key 0 does not exist. Then it will be created along with an empty vector as value and the valuemyInstanceOfData
will be pushed to this new vector inside the map.
Solution 3:
As the previous answer said, you can use emplace and std::move, but to test if it or any other solution works, I suggest you override the constructor, copy constructor, destructor, and the assignment operator to print something like created, copied, destroyed, assigned respectively, so you know what's actually going on, and improve performance.
Map in C++ with practical examples, An important characteristic of the map collection is that it orders elements by key in ascendingDuration: 19:52
C++: struct pointer in map structure
Question:
I declared a struct like this, and the following data structures
struct piece{ int start, height, end; piece(int a, int b, int c){ start = a; height = b; end = c; }};vector<piece> piecesTog;map <int,piece*> data;
Then, when I read the elements I do this:
while(scanf("%d %d %d", &aux1, &aux2, &aux3) != EOF){ piecesTog.push_back( piece(aux1, aux2, aux3) ); data[a] = data[c] = &piecesTog[tam];}
Well, until now, I have had no problem.However, later in the program, I have to use the piece* part, to do so, I use an iterator like this
for(map< int, piecesTog* >::iterator it = data.begin(); it != data.end(); it++){ piece* aux = it->second; ... }
I want to have access to the structure that the it->second points, but I tried everything and nothing worked.
I printed the memory adress of it->second and &piecesTog[tam] and they are the same, but when I do (*aux).height or it->second->height they give number completely crazy, probably some trash.
I have no clue why that is happening.
If anyone has any idea how to fix it, I would appreciate it.
Solution:
while(scanf("%d %d %d", &aux1, &aux2, &aux3) != EOF){ piecesTog.push_back( piece(aux1, aux2, aux3) ); data[a] = data[c] = &piecesTog[tam];}
is almost certainly not following the Iterator invalidation rules.
piecesTog.push_back( piece(aux1, aux2, aux3) );
can trigger a resize which typically creates a new datastore, copies the elements from the old data store to the new one and then deletes the old datastore, leaving the pointers cached by
data[a] = data[c] = &piecesTog[tam];
dangling. When you use those pointers some time in the future, Ka-Blammo! Undefined Behaviour and an easily identified crash if you're lucky.
Insufficient information has been provided to supply a definitive solution, but here are a few general alternatives (in order of attractiveness):
If you know ahead of time the number ofpiece
s that will go intopiecesTog
, you canreserve
storage to eliminate the need to resize thevector
.
If elements are only added to the end of thevector
and no elements are ever removed, you can store the indexes of the elements rather than pointers to them. If the ordering never changes, the indexes will always refer to the correct elements no matter how many more items are added.
If it is possible to do so, rewrite the reader to load all of thepieces
intopiecesTog
and then build the maps.
The above options all assume thatpiecesTog
is assembled all at once and then left alone. If your insertion is more free-form, you sort the structure or you remove elements, you'll need to use a data structure with more favourable invalidation rules such asstd::list
.
Map or Structure in C, This tutorial will discuss using the map or structure to create a collection of variables in C. Map or Structure in C.
Related posts:
Write a comment: