I'm forming a very primitive hash table. How do I create a vector where each individual index can lengthen into its own list? Is it as simple as, for example, vector<list<int>> ?
Also, if I want each node of the linked list to hold two datatypes (i.e. a string word and the integer line numbers of the file it can be found in), is it possible? I imagine not.
vecotr<list<int> > seems fine to me.
For you second question, you can use
typedef std::pair<std::string, int> Item;
std::vector<std::list<Item> >
Related
I have a operation that continuously generates random solutions (std::vector<float>). I evaluate the solutions against a mathematical function to see their usefulness (float). I would like to store the top 10 solutions all the time. What would be the most efficient way to do this in C++?
I need to store both the solutions(std::vector) and their usefulness (float). I am performing several hundred thousands of evaluations and hence I am in need of an efficient solution.
Edit:
I am aware of sorting methods. I am looking for methods other than sorting and storing the values. Looking for better data structures if any.
You evaluate the float score() function for current std::vector<T> solution, store them in a std::pair<vector<T>, float>.
You use a std::priority_queue< pair<vector<T>, float> > to store the 10 best solutions based on their score, and the score itself. std::priority_queue is a heap, so it allows you to extract its max value according to a compare function that you can set up to compare score_a < score_b.
Store the first 10 pairs, then for each new one compare it with the top of the heap, if score(new) > score(10th) then insert(new) into the priority_queue p, and p.pop_back() to get rid of the old 10th element.
You keep doing this inside a loop until you run out of vector<T> solutions.
Have a vector of pair, where pair has 1 element as solution and other element as usefulness. Then write custom comparator to compare elements in the vector.
Add element at last, then sort this vector and remove last element.
As #user4581301 mentioned in comments, for 10 elements, you dont need to sort. Just traverse vector everytime, or you can also perform ordered insert in vector.
Here are some links to help you:
https://www.geeksforgeeks.org/sorting-vector-of-pairs-in-c-set-1-sort-by-first-and-second/
Comparator for vector<pair<int,int>>
I made an implementation of dfs in c++ by multimap container in this way:
multimap<int, int>g;
And we could add edges in the graph in this way:
g.insert(make_pair(1,2));
Now I'm going to implement the Khushkal Algorithm by multimap. But in this case I got one more extra data per node , the weight. So now I need to store, (1,2,3) for example , triple data in the multimap.
Then what will be the multimap declaration look like??
And how could I insert such nodes?
You will have to map an item on another item.
Pick what you would like to use as key. If you decide on one key and two values, you map an int on a pair of ints. You can also opt to use a pair as key and map it on an int.
If you just would like to store pairs or tuples of three items, it is better to use an (unordered)set of these data members.
Option 1:
multimap<int, pair<int,int>>
Option 2:
multimap<pair<int,int>,int>
Is it possible to store multiple different class types in a single std::list object?
I want to make multi-layered list that can store int and std::list as an element, and now am trying to use std::list for this purpose. I need to retrieve data from all the list from both top-level and subsequent layers too.
This question here is similar except that I want to use pre-defined class.
The following returns error at 4th line:
std::list<int> l;
std::list<int> subL;
l.push_back(1);
l.push_back(subL);
This returns error at 1st (and 3th according to the 1st line):
std::list l;
std::list<int> subL;
l.push_back(1);
l.push_back(subL);
You could declare list <void*> and store to it pointers to any of your objects. But another question will raise how you're going distinguish them to use? If you don't need to, it's OK.
You can store both types in a single value if you use something like boost::variant.
I have a problem with the creation of a hash of arrays. I need a Single Key - Multi Data system:
multimap <Type, vector<type> > var;
But how I can add elements to the vector?
Example: key = 3;
Now I need to append some elements into the vector whose key is 3.
Creating a temp-vector not an answer because I don't know when I need to input element into the vector with the current key.
sorry, understand my problem. i need fast-access struct, that will be operate with ~50,000 words with length ~20 each.
and i need something like tree.
also, have question:
how quick STL-structures, like vector,map,multimap and other?
What's wrong with std::map <KeyType, std::vector<SomeType> >, or some other collection as the value type? This gives you control over how to operate on the value collection. A multimap to me seems like a low-level form of std::map <KeyType, std::list<SomeType> >, but with none of the flexibility of a list.
To find the answer to your question you can look at the slides under point 6. at this site https://ece.uwaterloo.ca/~ece250/Lectures/Slides/
Hope that helps!
Let's say we have read these values:
3
1241
124515
5322353
341
43262267234
1241
1241
3213131
And I have an array like this (with the elements above):
a[0]=1241
a[1]=124515
a[2]=43262267234
a[3]=3
...
The thing is that the elements' order in the array is not constant (I have to change it somewhere else in my program).
How can I know on which position does one element appear in the read document.
Note that I can not do:
vector <int> a[1000000000000];
a[number].push_back(all_positions);
Because a will be too large (there's a memory restriction). (let's say I have only 3000 elements, but they're values are from 0 to 2^32)
So, in the example above, I would want to know all the positions 1241 is appearing on without iterating again through all the read elements.
In other words, how can I associate to the number "1241" the positions "1,6,7" so I can simply access them in O(1) (where 1 actually is the number of positions the element appears)
If there's no O(1) I want to know what's the optimal one ...
I don't know if I've made myself clear. If not, just say it and I'll update my question :)
You need to use some sort of dynamic array, like a vector (std::vector) or other similar containers (std::list, maybe, it depends on your needs).
Such data structures are safer and easier to use than C-style array, since they take care of memory management.
If you also need to look for an element in O(1) you should consider using some structures that will associate both an index to an item and an item to an index. I don't think STL provides any, but boost should have something like that.
If O(log n) is a cost you can afford, also consider std::map
You can use what is commonly refered to as a multimap. That is, it stores Key and multiple values. This is an O(log) look up time.
If you're working with Visual Studios they provide their own hash_multimap, else may I suggest using Boost::unordered_map with a list as your value?
You don't need a sparse array of 1000000000000 elements; use an std::map to map positions to values.
If you want bi-directional lookup (that is, you sometimes want "what are the indexes for this value?" and sometimes "what value is at this index?") then you can use a boost::bimap.
Things get further complicated as you have values appearing more than once. You can sacrifice the bi-directional lookup and use a std::multimap.
You could use a map for that. Like:
std::map<int, std::vector<int>> MyMap;
So everytime you encounter a value while reading the file, you append it's position to the map. Say X is the value you read and Y is the position then you just do
MyMap[X].push_back( Y );
Instead of you array use
std::map<int, vector<int> > a;
You need an associative collection but you might want to associated with multiple values.
You can use std::multimap< int, int >
or
you can use std::map< int, std::set< int > >
I have found in practice the latter is easier for removing items if you just need to remove one element. It is unique on key-value combinations but not on key or value alone.
If you need higher performance then you may wish to use a hash_map instead of map. For the inner collection though you will not get much performance in using a hash, as you will have very few duplicates and it is better to std::set.
There are many implementations of hash_map, and it is in the new standard. If you don't have the new standard, go for boost.
It seems you need a std::map<int,int>. You can store the mapping such as 1241->0 124515->1 etc. Then perform a look up on this map to get the array index.
Besides the std::map solution offered by others here (O(log n)), there's the approach of a hash map (implemented as boost::unordered_map or std::unordered_map in C++0x, supported by modern compilers).
It would give you O(1) lookup on average, which often is faster than a tree-based std::map. Try for yourself.
You can use a std::multimap to store both a key (e.g. 1241) and multiple values (e.g. 1, 6 and 7).
An insert has logarithmic complexity, but you can speed it up if you give the insert method a hint where it can insert the item.
For O(1) lookup you could hash the number to find its entry (key) in a hash map (boost::unordered_map, dictionary, stdex::hash_map etc)
The value could be a vector of indices where the number occurs or a 3000 bit array (375 bytes) where the bit number for each respective index where the number (key) occurs is set.
boost::unordered_map<unsigned long, std::vector<unsigned long>> myMap;
for(unsigned long i = 0; i < sizeof(a)/sizeof(*a); ++i)
{
myMap[a[i]].push_back(i);
}
Instead of storing an array of integer, you could store an array of structure containing the integer value and all its positions in an array or vector.