I am trying to set the values of all elements in 2D vector to a particular value. As far as I am aware of, one cannot use memset for vectors like how they are used for arrays. Hence I have to use std::fill to set all elements in 2D vector to a particular value. However, I am aware of how to use fill for a 1D vector as show below.
vector<int> linearVector (1000,0);
fill(linearVector.begin(),linearVector.end(),10);
However, when I try to do something similar for a 2D vector(as shown below) it does not work.
vector<vector<int> > twoDVector (100,vector <int> (100,0));
fill(twoDVector.begin(),twoDVector.end(),10);
PS: I am aware that I can easily design a nested for loop to manually set the elements of the 2D vector to the value I want. However, It is not feasible in my program as the size of the 2D vector is quite large and there are other time consuming functions(recursive functions) happening in parallel.
In C++17 you can do it as below:
#include <algorithm>
#include <execution>
#include <vector>
//...
std::for_each(std::execution::par_unseq, nums.begin(), nums.end(),
[](std::vector<int>& vec) {
std::for_each(std::execution::par_unseq, vec.begin(), vec.end(),
[](int& n) {n = 10;});}
);
It seems to be parallel, but not as clear as simple fill function ;)
Of course you can pass your own variable instead of hardcoded 10.
This should help you
std::vector<std::vector<int> > fog(
A_NUMBER,
std::vector<int>(OTHER_NUMBER)); // Defaults to zero initial value
Reference: Initializing a two dimensional std::vector
You could use like this:
fill(twoDVector.begin(), twoDVector.end(), vector<int>(100, 10));
Related
I have a 3D vector :
vector<vector<vector<char>>> children;
this vector contains multiple 2D vectors and I would like to sort them based on a 1D vector:
vector<int> score;
each 2D vector in children is associated with a value in score. I have tried multiple similar questions but with no luck, so I was wondering how different the case of 3D vectors or is it even possible to sort with a vector of a different dimension in the first place?
I'm still fairly new to C++.
If your goal is to sort the scores and maintain the sorted scores with their relative position in the 3D vector, as the comment suggested and based on this answer, you can sort an array of indices that are based on the score criteria.
After sorting the indices, you use the indices to "point to" each sorted item in the 3D vector.
Here is an example:
#include <algorithm>
#include <vector>
#include <numeric>
int main()
{
std::vector<std::vector<std::vector<char>>> children;
std::vector<int> score;
//...
// Assume score and children have values
//...
// Sort the 3D vector based on the scores
// Set up the index vector
std::vector<int> index(score.size());
std::iota(index.begin(), index.end(), 0);
//...
// sort the indices based on the scores
std::sort(index.begin(), index.end(), [&](int n1, int n2)
{ return score[n1] < score[n2]; });
//...
// Do something with the "sorted" 3D vector
// The first sorted child is children[index[0]], the second is children[index[1]], etc.
}
Note that the linked answer has a thorough explanation of why and when this technique is used.
Object-orientation may help you here.
As the first step in that direction, you could make the type of children to be this:
std::vector<std::pair<std::vector<std::vector<char>>, int>> children;
(The first component of the std::pair<> is your "2D data"; its second component is the scores.)
As for how to sort this, use the sorting capabilities that the C++ standard library already makes available to your outer std::vector<> (i.e., std::sort()). Instead of using its often-used std::less<> criteria, you would formulate something that knows the format of the std::pair<> and accesses the score portion of it.
Next, also consider encapsulating that entire std::pair<> as a user-defined type (i.e., define yourself a class which has both your "2D data" and the scores as data members), and use your newly-defined type in place of this std::pair<>.
The result is programming that is easier to maintain and work with (including doing manipulations like sorting):
std::vector<YourNewType> children;
I am trying to make a bunch of (12) 15x15 vectors and I would like to have them all in a list or something like that that will allow me to easily access one of the vectors and edit them, as well as be able to have a number assigned to each vector to easily tell them apart. While I know I could make 12 vectors with their own names, I would like to know how I could do this in a less intensive way.
I have the dimensions and the number of the vectors in constant ints in a header file, and preferably I would like to use these as well, but this is not necessary.
Create a vector of vector of vectors of integers.
I use it all the time.
#include <iostream>
#include <string>
#include <vector>
int main()
{
std::vector<int> v(15,1);
std::vector<std::vector<int>> v1(15,v);
std::vector<std::vector<std::vector<int>>> vec(12,v1);
auto i = vec[2][2];
std::cout << i[2];
}
If size of dimensions are compile time constant, in order to keep stack tiny use vector for the top ranked dimension and array for the others:
using vec2d=std::array<std::array<int,15>,15>;
using vec3d=std::vector<vec2d>;
vec3d v1;
v1.resize(12);
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.
I have an std matrix defined as:
std::vector<std::vector<double> > Qe(6,std::vector<double>(6));
and a vector v that is:
v{0, 1, 3, 2, 4, 5};
I would like to swap the columns 3 and 2 of matrix Qe like indicated in vector v.
In Matlab this is as easy as writing Qe=Qe(:,v);
I wonder if there is an easy way other than a for loop to do this in c++.
Thanks in advance.
Given that you've implemented this as a vector of vectors, you can use a simple swap:
std::swap(Qe[2], Qe[3]);
This should have constant complexity. Of course, this will depend on whether you're treating your data as column-major or row-major. If you're going to be swapping columns often, however, you'll want to arrange the data to suit that (i.e., to allow the code above to work).
As far as doing the job without a for loop when you're using row-major ordering (the usual for C++), you can technically eliminate the for loop (at least from your source code) by using a standard algorithm instead:
std::for_each(Qe.begin(), Qe.end(), [](std::vector<double> &v) {std::swap(v[2], v[3]); });
This doesn't really change what's actually happening though--it just hides the for loop itself inside a standard algorithm. In this case, I'd probably prefer a range-based for loop:
for (auto &v : Qe)
std::swap(v[2], v[3]);
...but I've never been particularly fond of std::for_each, and when C++11 added range-based for loops, I think that was a superior alternative to the vast majority of cases where std::for_each might previously have been a reasonable possibility (IOW, I've never seen much use for std::for_each, and see almost none now).
Depends on how you implement your matrix.
If you have a vector of columns, you can swap the column references. O(1)
If you have a vector of rows, you need to swap the elements inside each row using a for loop. O(n)
std::vector<std::vector<double>> can be used as a matrix but you also need to define for yourself whether it is a vector of columns or vector of rows.
You can create a function for this so you don't write a for loop each time. For example, you can write a function which receives a matrix which is a vector of columns and a reordering vector (like v) and based on the reordering vector you create a new matrix.
//untested code and inefficient, just an example:
vector<vector<double>> ReorderColumns(vector<vector<double>> A, vector<int> order)
{
vector<vector<double>> B;
for (int i=0; i<order.size(); i++)
{
B[i] = A[order[i]];
}
return B;
}
Edit: If you want to do linear algebra there are libraries that can help you, you don't need to write everything yourself. There are math libraries for other purposes too.
If you are in a row scenario. The following would probably work:
// To be tested
std::vector<std::vector<double> >::iterator it;
for (it = Qe.begin(); it != Qe.end(); ++it)
{
std::swap((it->second)[2], (it->second)[3]);
}
In this scenario I don't see any other solution that would avoid doing a loop O(n).
I am looking for an efficient method for selecting access to each element of a std::vector<T> in a random order, without reshuffling or copying them i.e no use of std::random_shuffle and ensure that each element is selected only once.
I don't want to copy or reshuffle as a) each instance of T is likely to be a very large object and b) for other operations I will be doing on the elements of the vector, it is easier for them to remain in the same order.
Furthermore, I don't really want to go down the street of continuously picking and rejecting duplicates. It is likely I will have lots of these large objects stored in the vector and efficiency is key as I will be looking to call this random selection method many times a second.
Create a vector the same size as the existing one that uses pointers to the elements in the vector. Randomly shuffle the pointer vector instead and read from there - it's low cost.
You did not tell us whether you want to iterate over the whole array randomly, or if you only need some elements at random.
I assume the first case. You'll need extra storage for bookkeeping, and you'll need linear time for the shuffling anyway. So create a permutation, and keep its memory alive so that you can reshuffle it as you wish. With C++11:
#include <algorithm>
#include <random>
#include <numeric>
struct permutation
{
permutation(size_t n)
: perm(n), g(std::random_device())
{
std::iota(perm.begin(), perm.end(), size_t(0));
}
void shuffle() { std::shuffle(perm.begin(), perm.end(), g); }
size_t operator[](size_t n) const { return perm[n]; }
private:
std::vector<size_t> perm;
std::mt19937 g;
};
Usage:
std::vector<huge_t> v;
...
permutation sigma(v.size());
sigma.shuffle();
const huge_t& x = v[sigma[0]];
...
sigma.shuffle(); // No extra allocation
const huge_t& y = v[sigma[0]];
You can adapt the code to use C++03 std::random_shuffle, but please note that there are very few guarantees on the random number generator.
I think the easiest (and one of the more efficient ones) solution would be to either create a std::vector<size_t> holding indices into your vector<T>, or a std::vector<T*> holding the pointers into your vector. Then you can shuffle that one using std::random_shuffle, iterate over it and pick the corresponding elements from your original vector. That way you don't change the order of your original vector and shuffleing pointers or size_t is pretty cheap