I have a graph representation which looks like this
vector<int> Graph[MAXN]
Next, I want to remove all previously set vectors. What is the fastest way to do it ?
There's no real question of "efficiency" here. You must iterate through your array, and you must invoke std::vector<int>::clear() on each element of that array. So, just do it:
for (auto& v : Graph) {
v.clear();
}
Related
I am trying to group the pair vector vector<pair<int,int>> by the second value of it. For example, if the pair is v0 : (0,1),(1,1),(3,2),(4,2),(5,1). I want to get two outputs. The first one is the unique element of the second elements, which is
vector<int> v2={1,2};
The second is groups of the first elements, which could be
vector<vector<int>>v1;
v1[0]={0,1,5};
v1[1]={3,4};
How to achieve this in a efficient way? Do I need to sort the v0 by the second element at first before the group process? Does std::map is a faster way? Not only the method, I also concern about the speed. Because my v0 is a very long and unsorted triangle mesh vertices index list. Any suggestion will be appreciate.
Updated, I found one solution similar to link. It is in an unsorted way. I have no idea about its speed.
map<int, vector<int> > vpmap;
for (auto it = v0.begin(); it != v0.end(); ++it) {
vpmap[(*it).second].push_back((*it).first);
};
in which, vpmap.first is corresponding to v2; and vpmap.second is corresponding to v1.
What you have is a reasonably performant way of getting the exact data structures you're looking for. Be sure you pre-allocate the vectors since you know the size, and use move iterators to avoid unnecessary copying:
std::vector<int> v0;
std::vector<std::vector<int>> v1;
v0.reserve(vpmap.size());
std::transform(vpmap.begin(), vpmap.end(), std::back_inserter(v0), [](auto p) { return p.first; });
v1.reserve(vpmap.size());
std::transform(make_move_iterator(vpmap.begin()), make_move_iterator(vpmap.end()), std::back_inserter(v1), [](auto p) { return p.second; });
If you can loosen your constraints, do think about big-picture optimizations like "do I need to transform all this data?"
But once you have something reasonable, stop worrying about the fastest techniques or containers or whatever, and start measuring with a profiler. Sometimes the stuff you worry about winds up being a non-issue and there are non-obvious costs that stem from your problem domain and input data and accumulation of code
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 4 years ago.
Improve this question
I have n vectors and I need to iterate over all of them consistently.
I mean that first I need to iterate over all elements of first vector then to iterate over all elements of second vector and so on.
I have task to compare all elements consistently including the last element of k-1'th vector and first element of k'th vector.
I know the solution where I first concatanete all this vectors in one big final vector and then iterate over final vector.
But it seems to me that this solution wastes a lot of memory and time.
Please help me to find more optimized solution.
If it exists.
For example, with complexities: O(1) additional memory and O(n) time .
A simple approach would be to use two nested loops.
In C++11 and later, simply do
std::vector<std::vector<int> > vec;
// some code that sets up the vectors in vec
for (auto &v : vec) // iterate over the vectors in vec
{
for (auto &e : v) // iterate over the elements of v
{
// do whatever is needed to element e
}
}
If need be, v and e may be const qualified (to indicate not changing the vectors or their elements). The total number of iterations will be the number of elements of the contained vectors. The additional memory usage will be (at any point in time in the inner loop) two sets of references - one set for controlling the inner loop and one for the outer loop (i.e. no copies of the vectors or elements themselves).
Before C++11, the above loops can be rewritten less verbosely using for loops that work with iterators rather than ranges;
for (std::vector<std::vector<int> >::iterator v(vec.begin()), vend(vec.end());
v != vend; ++v)
{
for (std::vector<int>::iterator e(v->begin()), eend(v->end());
e != eend; ++e)
{
// do whatever is needed to element *e
}
}
Note the need to dereference iterators in this form.
If you only need something that can be iterated over, you probably want something like ranges::view::concat
Given N source ranges, produce a result range that is the concatenation of all of them.
This doesn't copy any values, so is O(1) storage and O(1) time.
If the thing you need is exactly std::vector<MyClass>, then you are out of luck, you will have to populate a vector with all the values.
I am relative new at C++ and I have little problem. I have vector and in that vector are vectors with 3 integers.
Inner vector represents like one person. 3 integers inside that inner vector represents distance from start, velocity and original index (because in input integers aren't sorted and in output I need to print original index not index in this sorted vector).
Now I have given some points representing distance from start and I need to find which person will be first at that point so I have been thinking that my first step would be that I would find closest person to the given point so basically I need to find lower_bound/upper_bound.
How can I use lower_bound if I want to find the lower_bound of first item in inner vectors? Or should I use struct/class instead of inner vectors?
You would use the version of std::lower_bound which takes a custom comparator (the versions marked "(2)" at the link); and you would write a comparator of vectors which compares vectors by their first item (or whatever other way you like).
Howerver:
As #doctorlove points out, std::lower_bound doesn't compare the vectors to each other, it compares them to a given value (be it a vector or a scalar). So it's possible you actually want to do something else.
It's usually not a good idea to keep fixed-length sequences of elements in std::vector's. Have you considered std::array?
It's very likely that your "vectors with 3 integers" actually stand for something else, e.g. points in a 3-dimensional geometric space; in which case, yes, they should be in some sort of class.
I am not sure that your inner things should be std::vector-s of 3 elements.
I believe that they should std::array-s of 3 elements (because you know that the size is 3 and won't change).
So you probably want to have
typedef std::array<double,3> element_ty;
then use std::vector<element_ty> and for the rest (your lower_bound point) do like in einpoklum's answer.
BTW, you probably want to use std::min_element with an explicit compare.
Maybe you want something like:
std::vector<element_ty> vec;
auto minit =
std::min_element(vec.begin(), vec.end(),
[](const element_ty& x, const element_ty&y) {
return x[0] < y[0]));
I'm trying to find a way to improve my answer here. Let's simplify the question to say: I want to partition the input container, lets call it foo, into a vector of vectors of size STEP, the last of these vectors shall have a smaller size if there were less than STEP elements remaining in the input container, let's call this partitioned container bar.
I don't want to iterate over my input or output range multiple times. The element of the problem I'm trying to solve are simply:
Append bar with a constructed vector of size min(STEP, distance(it, foo.end())
Have the it point to advance(it, size(bar.back())) after constructing the container
Do this vector construction in-place
The translation of my answer to the confines of this problem is:
auto it = cbegin(foo);
for (auto i = size(foo); i > STEP; i -= STEP) {
bar.push_back(decltype(bar)::value_type(STEP));
for (auto internalIt = bar.back().begin(); internalIt != bar.back().end(); ++internalIt, ++it) {
*internalIt = *it;
}
}
bar.push_back(decltype(bar)::value_type(it, cend(foo)));
The problem is this line: bar.push_back(decltype(bar)::value_type(STEP)) I'm allocating the vector and 0-initializing it's components. Is there a better way to do this, under which I still would only iterate over the input and output ranges once?
bar.push_back(decltype(bar)::value_type{}); // or bar.resize(bar.size() + 1); if you prefer
bar.back().reserve(STEP);
while (bar.back().size() < STEP) {
bar.back().push_back(*it);
++it;
}
It's a stroke of bad luck that std::copy_n returns the advanced output iterator, when what you need to keep is the advanced input iterator, otherwise you could use that in place of the loop (using std::back_inserter to get the destination iterator).
Feel free to use a counter variable if you're concerned about the performance of bar.back().size()!
I am using vector of vector to simulate a 2D array. In order to reuse this 2D array, sometimes I need to reset all its elements to zero or some default value. I know for a simple 1D vector I can do:
std::fill(v.begin(), v.end(), 0);
How to do that efficiently for a vector<vector<int>>? I hope to find a solution without using for loops but more akin to some memset variant. I also don't want to incur any memory allocation and deallocation since my intent was to reuse the existing allocated memory.
Note that I am assuming each vector's size is fixed and known to me: vector<vector<int>> v(const_max_size, vector<int> (const_max_size, 0));. How to reset v's elements to zero?
NOTE: What I mean by not using for loops is that I don't want to iterate over all the 2D elements using subscripts like v[i][j] to assign them the value.
I hope to find a solution without using for loops ...
Well, either you do a loop explicitly or use something that loops implicitly. Nothing wrong with explicit loops:
for (auto& sub : v) {
std::fill(sub.begin(), sub.end(), 0);
}
I guess technically if you want to avoid a loop you could use:
std::for_each(v.begin(), v.end(),
[](auto& sub) {
std::fill(sub.begin(), sub.end(), 0);
});
I know I am going to get flack for this answer, but I am sure there is nothing faster:
for(auto& x : v) memset(&x[0],0,sizeof(int)*x.size());
memset is highly optimized for setting to 0.