i using typedef boost::unordered_map. how to get a random element
v: c++ 03
code:
member_1.insert(std::make_pair(gg, M2_NEW CGGList(gg)));
typedef boost::unordered_map<CGG, CGGList*> Map1;
Map1 member_1;
You will not find an efficient method (wrong datastructure).
But you can always:
auto random_it = std::next(member1.begin(), my_random(member2.size()));
Where my_random would be implemented like rand()%n (bad) or using std::uniform_int_distribution<size_t> (much better).
Related
I have question with Boost::bimap and could not find answer from boost document.
using AToBBimap = boost::bimap< boost::bimaps::unordered_set_of<CString>, boost::bimaps::multiset_of<CString> >; //hashed bimap
using AToBBimapValueT = AToBBimap ::value_type;
AToBBimap bi_map;
bi_map.insert(AToBBimapValueT{"message1", "value"});
bi_map.insert(AToBBimapValueT{"message2", "value"});
bi_map.right.find("value");
QUESTION: with bi_map.right.find("value") looks like can only get iterator to {"message1", "value"}, is there possible to get a list of both matching like [{"message1", "value"}, {"message2", "value"}]?
The answer is equal_range("value"), like with std::multiset and std::multimap.
That member returns a pair of iterators, which is conveniently compatible with Boost's iterator-range factory, so you can use it:
for (auto p : boost::make_iterator_range(bi_map.right.equal_range("value")))
do something with p.second;
I just have this:
std::vector<int[2]> ints;
how can I add elements to this vector?
using either ints.insert() or ints.push_back()?
No idea how to do this, C/C++ newb.
With C++ 11:
std::vector<std::tuple<int, int, int>> vec;
vec.emplace_back(0, 1, 2);
Here is a way you can achieve the functionality you are looking for:
std::vector<std::tuple<int, int>> ints;
Then you would add a tuple to the vector like this:
ints.push_back(std::make_tuple(1, 2));
Edit/Update:
if you were looping over you vector and i is your integer index used during the loop, then to access to tuple you can do this:
int intOne, intTwo;
intOne = std::get<0>(ints[i]);
intTwo = std::get<1>(ints[i]);
here is some more info on get for a tuple
You can use extract tuple using std::get
Here is the C++ 11 link with example:
http://en.cppreference.com/w/cpp/utility/tuple/get
The full article about tuples is here:
http://en.cppreference.com/w/cpp/utility/tuple
I am trying to write a sorting algorithm for the following unordered map. I have seen this question and I am trying to implement it for an unordered map, but it is not working!
Note- I am not allowed to use any STL sort functions.
void quickSort(unordered_map<string, int> map, unordered_map<string, int>::iterator left,unordered_map<string, int>::iterator right) {
unordered_map<string, int>::iterator i=left;
unordered_map<string, int>::iterator j=right;
unordered_map<string, int>::iterator pivot = std::advance(map.begin(), map.size() / 2);
unordered_map<string, int> tmp;
}
int main(){
unordered_map<string, int> map;
map["blah"] = 2;
map["the"] = 5;
quickSort(map,map.begin(),map.end());
}
As stated in the comments, you cannot sort a unordered_map in place because its value_type is std::pair<const Key, T> (note the const!) for an unordered_map<Key,T>. This means that you cannot swap elements in the map, so you cannot sort it. You will need to copy the data into another data-structure like a vector, then you can use some "home-grown" version of std::nth_element on it:
std::vector<std::pair<Key,T>> med {map.begin(), map.end()};
my_nth_element(med.begin(), med.end(), med.begin() + med.size() / 2);
auto median = med[med.size()/2];
You should implement your nth_element with linear complexity on average. (If the number of input values happens to be even, you need to use the mean of both middle-values.)
An unordered map does not have order(as its name implies) and thus finding the median in an unordered map does not make sense. If you need to find the median - use a auxiliary array and perform some implementation of nth_element algorithm in it. This step would be with linear complexity.
I need to find an element in a vector<pair<int, float>> and increase the second value.
I tried an approach.
template <typename K, typename V>
struct match_first {
const K _k; match_first(const K& k) : _k(k) {}
bool operator()(const pair<K, V>& el) const {
return _k == el.first;
}
};
Eg to use.:
vector< pair<int, float> > vec;
vec.push_back(make_pair(2, 3.0));
vec.push_back(make_pair(3, 5.0));
vec.push_back(make_pair(1, 1.0));
vector< pair<int, float> >::iterator it = find_if(vec.begin(), vec.end(), match_first<int, float>(3));
if (it != vec.end()) {
it->second += 9;
}
There is a more efficient way of accomplishing this task?
A map seems more natural:
#include <map>
int main()
{
std::map<int, float> m;
m.insert(std::make_pair(2, 3.0));
m.insert(std::make_pair(3, 5.0));
m.insert(std::make_pair(1, 1.0));
auto it = m.find(3);
if (it != m.end()) {
it->second += 9;
}
}
It will also be faster because lookup is O(log(n))
You can reach the same complexity with a vector of sorted pairs by using std::lower_bound (or std::equal_range if keys can be repeated)
It depends on your constrains. If you have the unique key (the first element) you can use std::map<K,V> to hold your objects. Then increasing it is easy. If V has a default constructor initializing it to zero, you can even skip adding new elements and just increment (I am not sure it will work with ints through).
std::map<K,V> data;
data[key] = data[key] + 1;
the [] operator used for non-existent key will create the object for you using its default constructor. To just access data use at or find methods.
extending sehe's answer: You can use std::multimap in the same way if you may have duplicate keys. This container also keeps the <K,V> pair in sorted order(keys) so binary search approach obviously speed up things.
There is no exact answer to your question: it depends.
My first answer is: use std::find_if (available in <algorithm>, part of the C++ Standard Library), then profile your code. If the search turns out to be a bottleneck worthy of concern, then try another approach.
Beware of using a std::map, as it will sort the pairs by their first component (that is, the insertion order will be lost). In addition, it will not allow you to store two pairs with the same first component.
As others have mentioned, you can work around this caveats (if they are indeed caveats to your problem), but, like I mentioned before, it would only be worth your while if you demonstrate first that the search turned out to be a bottleneck after using the standard algorithms.
This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
Checking value exist in a std::map - C++
How to traverse a stl map/vector/list/etc?
Hello,
Is it possible to search for specific value in std::map, not knowing the key? I know I could iterate over whole map, and compare values, but it is possible to do using a function from std algorithms?
Well, you could use std::find_if :
int main()
{
typedef std::map<int, std::string> my_map;
my_map m;
m.insert(std::make_pair(0, "zero"));
m.insert(std::make_pair(1, "one"));
m.insert(std::make_pair(2, "two"));
const std::string s("one");
const my_map::const_iterator it = std::find_if(
m.begin(), m.end(), boost::bind(&my_map::value_type::second, _1) == s
);
}
But that's just slightly better than a hand-crafted loop : it's still O(n).
You could use Boost.Bimap if you want to index on values as well as keys. Without this or similar, this will have to be done by brute force (=> scan the map by hand).
Boost.Bimap is a bidirectional maps
library for C++. With Boost.Bimap you
can create associative containers in
which both types can be used as key.
Will this help? STL find_if
You need to have some sort of predicate, either a function pointer or an object with operator() implemented. Said predicate should take just one parameter.
There are (awkward) ways to do this using standard functions (e.g., std::find_if), but these still involve iterating over the whole map. Boost.Bimap will provide efficient indexing in both directions, and you can go even further with Boost.Multi-Index.