I have the following piece of code:
map<int, set<int>> my_map;
int my_int1, my_int2;
// some code
set<int> temp;
temp.insert(my_int2);
my_map.insert(make_pair(my_int1, temp));
Is there some way to avoid using the temp (at least just for the code to look nicer, not necessarily for performance) and use an anonymous object? Something like:
my_map.insert(make_pair(my_int1, (set<int>{}).insert(my_int2)));
Except, the above line doesn't compile.
Not tested but try something like this:
my_map.insert({my_int1, {my_int2}});
Ok, let's sumarize. There is an important thing to know about insert: the insert doesn't insert if key already exists.
//create and initialise inline a map with int keys and string values
map<int, string> x {
{10, "hello"},
{123, "bye"},
{234, "world"}
};
x.insert({567, "alien"}); //inserts an element initialised inline
x.insert({567, "bar"}); //does nothing, according to specs
x[124] = "buzz"; //inserts an element
x[567] = "bar"; //modifies the element with key 567
//create and initialise inline a map with int keys and int values
map<int, string> y {
{10, 1},
{123, 2},
{234, 3}
};
y.insert({567, 4}); //insert an element initialised inline
z[124] = 5; //inserts
z[124] = 6; //modifies the above element
z[125]++; //inserts and modifies, now z[125] is 1
z[125]++; //modifies the above element to 2
It is very flexible. If you create a map of containers
//create and initialise inline a map with int keys and set values
map<int, set<int>> x {
{10, {1, 2, 3}},
{123, {2, 3}},
{234, {1, 2, 3}}}
};
//calling insert on map:
y.insert({567, {4, 5, 6}}); //element 567 has the value {4, 5, 6}
//now this calls insert in the set:
y[567].insert(7); //element 567 exists, so it is modified to {4, 5, 6, 7}
y[568].insert(7); //element 569 doesn't exist, so it is created first
//assign
y[235] = {4, 5, 6}; //element 235 has the value {4, 5, 6}
y[235] = {7, 8, 9}; //element 235 has the value {7, 8, 9}
y[235].insert(10); //element 235 has the value {7, 8, 9, 10}
You need none of your intermediate steps!
int main()
{
std::map<int, std::set<int>> my_map;
my_map.insert({1,{}});
}
You don't need the temporary std::set at all. Simply use std::map::operator[] to create the std::set in the std::map if it doesn't already exist, and then you can insert() into that std::set directly, eg:
map<int, set<int>> my_map;
int my_int1, my_int2;
// some code
my_map[my_int1].insert(my_int2);
Related
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 2 years ago.
Improve this question
I have a Vector of pairs (std::vector<pair<int, int>>) with sorted order by first of pair. I wanna update the second value of the pair by searching the first value of the pair.
vector<pair<int,int>> v = { {1, 5}, {4, 26}, {5, 3}, {7, 13}, {12, 43}, {17, 31} };
I would like to update the second value of the pair as 27 which has a first value 12.
// Expected v
v = { {1, 5}, {4, 26}, {5, 3}, {7, 13}, {12, 27}, {17, 31} }
Remember that vector was already sorted by the first element of pair.
You can perform a binary search on a sorted vector using std::lower_bound. The result is the iterator to the first element greater or equal than the argument. You have to manually compare the result for an exact match.
auto it = std::lower_bound(v.begin(), v.end(), std::make_pair(12, 0));
if (it != v.end() && it->first == 12) {
it->second = 27;
}
use std::map
std::map<int, int> mymap;
mymap = { {1, 5}, {4, 26}, {5, 3}, {7, 13}, {12, 27}, {17, 31} };
int newValue = 5;
mymap.at(12) = newValue; //update the value 27 here
std::cout << mymap.at(12) << std::endl;
Note that at function will throw an out of range exception if requested element is missing from map.
Also, like your vector, this map is sorted.
I'm looking for some pointers on inserting or pushing a vector into another vector.
The idea is I have vec1 = {1, 2, 3} for example.
Then I want to insert this into vec2 before next vec1 = {4, 5, 6} turns up.
The problem is I don't want vec 2 to read {1, 2, 3, 4, 5, 6}, I want it to read
vec2 = {1, 2, 3},
{4, 5, 6},... etc
Is this possible or I'm I completely mad. Any help will be great.
Thanks.
You can use a vector of vector of integers. Like this :
std::vector<std::vector<int>> vecofvecs = { {1,2,3}, {4,5,6} };
You can also use this :
#include <vector>
int main()
{
std::vector<std::vector<int>> vecofvecs;
std::vector<int> subvec1 = { 1,2,3 };
std::vector<int> subvec2 = { 4,5,6 };
vecofvecs.push_back(subvec1);
vecofvecs.push_back(subvec2);
return 0;
}
I'm aware how to generate all possible subsets from a set incorporating bit twiddling. For instance,
//Get if nth position's bit is set
bool IsBitSet(int num, int bit)
{
return 1 == ((num >> bit) & 1);
}
int subsetMaxIterCount = pow(2, someList.size());
for (int i = 0; i < subsetMaxIterCount; i++) {
vector<A> subset;
for (size_t i = 0; i < jobList.size(); i++)
{
if (IsBitSet(jobSubsetIdx, i)) {
//Add to subset here
}
}
//Here we have a subset for some i
}
However, this doesn't take into account of ordering.
For instance, if I had a set of {1, 2, 3}, the above algorithm generates subsets of:
{}, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1,2,3}
What I need in reality is this
{}, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1,2,3}, {2, 1}, {2, 1, 3}, {2, 3, 1}, {3, 1}, {3, 2}, {3, 1, 2}, {3, 2, 1}
Not sure if the above list is exhaustive. What's an effective algorithm in generating something like this? (Is this all possible subsets with permutation by the way?)
The way we generate the subsets using bit twiddling, every subset is sorted within it e.g. {1, 2, 3}, {2, 3}, {1, 3}. You can generate permutation for each subset using next_permutation
vector<vector<int>> mySubsetGenerator(vector<vector<int>>& subsets) {
vector<vector<int>> extendedSubset;
for(int i = 0; i < subsets.size(); ++i) {
do {
extendedSubset.push_back(subsets[i]);
} while(next_permutation(subsets[i].begin(), subsets[i].end()));
}
return extendedSubset;
}
Moreover, you can use only backtracking to generate all possible permutations by taking one or more elements of array.
While there are plenty of examples on how to generate the actual power set of a set, I can't find anything about iteratively (as in std::iterator) generating the power set. The reason why I would appreciate such an algorithm is the size of my base set. As the power set of a n-element set has 2^n elements, I would quickly run out of memory when actually computing the set. So, is there any way to create an iterator for the power set of a given set? Is it even possible?
If it would be easier, an iterator that creates sets of ints would be fine - I could use them as indices for the actual set/vector.
As I actually work on a std::vector, random access would be possible if neccessary
Using for_each_combination from Combinations and Permutations one can easily iterate through all members of the power set of a std::vector<AnyType>. For example:
#include <vector>
#include <iostream>
#include "../combinations/combinations"
int
main()
{
std::vector<int> v{1, 2, 3, 4, 5};
std::size_t num_visits = 0;
for (std::size_t k = 0; k <= v.size(); ++k)
for_each_combination(v.begin(), v.begin()+k, v.end(),
[&](auto first, auto last)
{
std::cout << '{';
if (first != last)
{
std::cout << *first;
for (++first; first != last; ++first)
std::cout << ", " << *first;
}
std::cout << "}\n";
++num_visits;
return false;
});
std::cout << "num_visits = " << num_visits << '\n';
}
This visits each power set member of this vector, and executes the functor, which simply counts the number of visits and prints out the current power set:
{}
{1}
{2}
{3}
{4}
{5}
{1, 2}
{1, 3}
{1, 4}
{1, 5}
{2, 3}
{2, 4}
{2, 5}
{3, 4}
{3, 5}
{4, 5}
{1, 2, 3}
{1, 2, 4}
{1, 2, 5}
{1, 3, 4}
{1, 3, 5}
{1, 4, 5}
{2, 3, 4}
{2, 3, 5}
{2, 4, 5}
{3, 4, 5}
{1, 2, 3, 4}
{1, 2, 3, 5}
{1, 2, 4, 5}
{1, 3, 4, 5}
{2, 3, 4, 5}
{1, 2, 3, 4, 5}
num_visits = 32
The syntax I've used above is C++14. If you have C++11, you will need to change:
[&](auto first, auto last)
to:
[&](std::vector<int>::const_iterator first, std::vector<int>::const_iterator last)
And if you are in C++98/03, you will have to write a functor or function to replace the lambda.
The for_each_combination function allocates no extra storage. This is all done by swapping members of the vector into the range [v.begin(), v.begin()+k). At the end of each call to for_each_combination the vector is left in its original state.
If for some reason you want to "exit" the for_each_combination early, simply return true instead of false.
How to initialize a 2 dimensional vector<int> in C++?
For instance I have 4 arrays each of length 8 ints, like the below
int a1[] = {1,2,3,4,5,6,7,8};
int a2[] = {1,2,3,4,9,10,11,12};
int a3[] = {1,2,5,6,9,10,13,14};
int a4[] = {1,3,5,7,9,11,13,15};
and I have this
vector< vector <int> > aa (4);
aa[i] (a1,a1+8);
But this gives error. I even tried supplying the array a1 to v1 and passed v1 to aa[i] , still it fails.
So what would be the proper way of initializing the elements of a 2 dimensional vector<int>
aa[i].assign(a1,a1+8);
int arr[4][8] =
{
{1, 2, 3, 4, 5, 6, 7, 8},
{1, 2, 3, 4, 9, 10, 11, 12},
{1, 2, 5, 6, 9, 10, 13, 14},
{1, 3, 5, 7, 9, 11, 13, 15},
};
std::vector<std::vector<int> > vec(4, std::vector<int>(8));
for (int i = 0; i < 4; ++i)
{
vec[i].assign(arr[i], arr[i] + 8);
}
The initialization of aa also initialized all four of the contained vector<int> objects, using the default constructor for vector<int>. So you'll need to add data to those empty vectors, not initialize them.
Try for example:
std::copy(a1, a1+8, std::back_inserter(aa[i]));