Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
Here is my code
#include <iostream>
#include <map>
#include <string>
#include <vector>
typedef std::vector<int> VectorInt;
typedef std::map<int, VectorInt> MapVectorInt;
int main() {
MapVectorInt myMap;
VectorInt v1;
v1.push_back(1);
v1.push_back(3);
v1.push_back(5);
VectorInt v2;
v2.push_back(2);
v2.push_back(4);
v2.push_back(6);
myMap.insert(std::make_pair(0, v1));
myMap.insert(std::make_pair(1, v2));
return 0;
}
What is the bese way to take (extract/get) the vector at position x (eg 1,2...);
You can use:
auto v1=myMap[0]; //This will do a deep copy for the vector
or:
auto& v1=myMap[0]; //This will hold a reference to the vector
Be careful in the second approach because if the item has removed , the reference will be invalid.
If you want a safe option use std::map::at:
auto v1=myMap.at(0);
or:
auto& v1=myMap.at(0)
This will throw an exception (std::out_of_range) if the item is not there.
Short answer:
Best place to look for it http://en.cppreference.com/w/cpp/container/map/find
With context:
For visualisation only, I guess you should express you intention as you said in your question(get an element from the map and not "eventually" insert it as using [] for accessing a non-existing element creates it), so:
const auto& search = myMap.find(1);
if (search != example.end()) {
for(auto value: search->second) {
std::cout << value << '\n';
}
}
else {
std::cout << "Not found\n";
}
Try It Live
You can refer to the vector in the map with myMap[0] or myMap[1].
You could make an alias for either of those, e.g. auto& x = myMap[0];. Using the alias will access the vector as it is stored in the map.
To take a copy of the vector (so that you can modify the map contents without changing the copy), it is just the same as copying any other object:
auto x = myMap[0];
Note that 0 and 1 refer to the key you used in the insert call; not to the search order or the insertion order (although in your example those things all happen to be the same).
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I have a for-loop that iterates over the stack of maps, but when I execute the code i get a segmentation fault. My code is this:
// std::stack< std::map<string, string> > STACK;
size_t getStackSize() { return this->STACK.size();}
std::stack< std::map<string, string> > getSTACK() { return this->STACK;}
for (size_t i = 0; i < ObjSTACK.getStackSize(); ++i )
{
for (auto& [v, l] : ObjSTACK.getSTACK().top())
{
std::cout << v << ':' << l << '\n';
}
ObjSTACK.getSTACK().pop();
}
Why am I getting the segmentation fault? Are there better ways to iterate over a std::stack< std::map<string, string> > ?
getStack() is returning a copy of the std::stack each time it is called, thus
while (!ObjSTACK.getSTACK().empty())
would be very inefficient at best, but
ObjSTACK.getSTACK().pop();
would be a no-op, since you are popping from a temp std::stack, not the original. Thus getStackSize() would not change value, and the outer loop would run forever.
Make getStack() return a reference instead, so that the loop can actually modify the std::stack:
std::stack< std::map<string, string> >& getSTACK() { return this->STACK; }
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I am working on a c++ code which includes a command schedule. I implement the schedule as a multimap container, with execution time,as the key, and command name I want to execute. I need to be able to time shift all the commands in the schedule.
I assume I can do that by copying the container to another container and erasing the original container, then changing the key values for each pair in the copy container and inserting it back in the original container, like the example code below.
#include <stdio.h>
#include <map>
int main() {
std::multimap<int,int> original,copy;
original.insert(std::pair<int,int>(10,1));
original.insert(std::pair<int,int>(10,2));
original.insert(std::pair<int,int>(12,3));
std::multimap<int,int>::iterator it;
copy=original;
it=original.begin();
original.erase(it,original.end());
int tctime;
int command;
for (it=copy.begin();it!=copy.end();it++){
tctime =(*it).first+5;
command=(*it).second;
original.insert(std::pair<int,int> (tctime, command));
}
return 0;
}
while this works, I would like to know if there is a better solution to implement it.
Although you should ask these kind of questions on Code Review, I will write my answer here also so it may help someone else (and since it is not yet closed).
First, since your question has a C++ tag, please use #include <iostream> instead of #include <stdio.h>.
Second, I suggest you to use std::make_pair instead of the std::pair constructor. std::make_pair automatically deduces types of the values passed to it so I would prefer it over std::pair where you need to specify the types. So, you should use something like this:
original.insert(std::make_pair(10,1));
Next, since you are erasing all the values from the std::multimap<int,int> original, why not just use std::multimap::clear? It is less code to write and your intention is more straightforward.
original.clear()
instead of
it=original.begin();
original.erase(it,original.end());
Furthermore, I would suggest using range-for loops over the standard loops.
for (auto const& it : copy) {
tctime = it.first +5;
command = it.second;
original.insert(std::make_pair(tctime, command));
}
instead of
for (auto it = copy.begin(); it != copy.end(); it++){
tctime =(*it).first+5;
command=(*it).second;
original.insert(std::pair<int,int>(tctime, command));
}
And the last thing, good practice would be to initialize variables tctime and command to 0.
Full code:
#include <iostream>
#include <map>
int main() {
std::multimap<int,int> original,copy;
original.insert(std::make_pair(10,1));
original.insert(std::make_pair(10,2));
original.insert(std::make_pair(12,3));
copy=original;
original.clear();
int tctime = 0;
int command = 0;
for (auto const& it : copy) {
tctime = it.first +5;
command = it.second;
original.insert(std::make_pair(tctime, command));
}
return 0;
}
Here is the fully refactored code live.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
std::map<char*, int> mymap;
mymap['a'] = 1;
mymap['b'] = 2;
mymap['c'] = 3;
How to print 1, 2, 3 in that particular order if order of insertion gets changed?
I don't know the insertion order . But the order of output should be same everytime.
I don't know the insertion order . But the order of output should be same everytime.
This is exactly how std::map works. The iterators go through the element in the strict weak ordering induced by the comparator of the map. Insertion order does not affect the order of the iteration.
std::map<char*, int> How to print 1, 2, 3 in that particular order.
The problem here is that a map is ordered by the key rather than by value.
If you need to iterate over elements of a map in value-order, then it seems that you need a multi-index container. Such container can be looked up by one index, and iterated using another index. The C++ standard library does not provide such multi-index containers however.
The idea of multi-index container is quite simple. It consists of nodes just like a list or a tree does, but each node contains multiple sets of links - one for each index. A generic implementation of such container is not quite as simple as the idea is.
mymap['a'] = 1;
You cannot use a char as a lookup argument to a map whose key type is char*.
This is probably what you need:
std::map<char, int> mymap;
mymap.emplace(make_pair('a', 1));
mymap.emplace(make_pair('c', 3));
mymap.emplace(make_pair('b', 2));
for(auto& it : mymap)
cout<<it.second<<endl;
map is sorted based on the keys not the values, If you need a variable size char then use string
if char* is not optional use shared_ptr:
std::map<std::shared_ptr<char>, int> mymap;
mymap.emplace(make_shared<char>(char('a')), 1);
The main problem you have here is inserting a pointer as key means you always have unique key, for example two pointers point to different addresses in memory but the char stored in those addresses are the same which is not what you want from a map.
if you wanted to keep it sorted based on the values just change the key and value.
sort map by value:
#include <iostream>
#include <memory>
#include <algorithm>
#include <map>
using namespace std;
template<typename A, typename B>
std::pair<B,A> flip_pair(const std::pair<A,B> &p)
{
return std::pair<B,A>(p.second, p.first);
}
template<typename A, typename B>
std::multimap<B,A> flip_map(const std::map<A,B> &src)
{
std::multimap<B,A> dst;
std::transform(src.begin(), src.end(), std::inserter(dst, dst.begin()),
flip_pair<A,B>);
return dst;
}
int main(void)
{
std::map<std::shared_ptr<char>, int> mymap;
std::shared_ptr<char> a;
a.reset(new char('a'));
std::shared_ptr<char> b;
b.reset(new char('b'));
std::shared_ptr<char> c;
c.reset(new char('c'));
mymap.emplace(make_pair(a, 1));
mymap.emplace(make_pair(c, 2));
mymap.emplace(make_pair(b, 3));
std::multimap<int, std::shared_ptr<char>> dst = flip_map(mymap);
// dst is now sorted by what used to be the value in src!
for(auto& it : dst)
cout<<it.first<<endl;
}
credit of sorting map by value: https://stackoverflow.com/a/5056797/10933809
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I simply would like to initizlize an unordered_map with a vector.
When I have tried the code below, the code does not compile.
What is the shortest syntax to initilize unordered_map with a vector? How would you implement following method without using loop.
unordered_map<int, int> convertToMap(const vector<int>& v)
{
unordered_map<int, int> umap(v.begin(), v.end());
return umap;
}
I have found some resources, and I have tried to initialize through a range, but it does not worked either!
initialize-unordered-map
How to initialize unordered_map with vector?
If your vector contains pairs of elements, so that one could be interpreted as key and one as value then you can use range initialization:
#include <vector>
#include <unordered_map>
#include <iostream>
#include <utility>
int main()
{
std::vector<std::pair<int, int>> v = { {1,10}, {2,20}, {3,30} };
std::unordered_map<int, int> map(v.begin(), v.end());
std::cout << map[2] << std::endl;
return 0;
}
The above prints: 20
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I'm writing a C++ program using iterators. I have a data structure that is a map. I use iterators to loop from the begin to the end of the map and for each element of the map I do something with the key and the value.
So when I want to know the key and the value of a specific element of the map, I use first() and second() on my iterator.
Like this :
#include <map>
#include <pair>
map<unsigned long, int> myMap;
map<unsigned long, int>::const_iterator it;
for(it = myMap.cbegin(); it != myMap.cend(); ++it)
{
unsigned long key_of_map = it.first();
int val = it.second();
cout << "Key is : " << key_of_map << endl << "Value is : " << val << endl;
}
When I compile it, it tells me :
"../src/myfile.cpp:16:10: fatal error: 'pair' file not found"
I'm using Eclipse (version Luna), the standard version I downloaded from the official website (I didn't changed anything).
You need to
#include <utility>
to use std::pair<>