How do I manually enter in a Matrix of data? - c++

I just want to hard code in a matrix using C++ (g++ 4.1.2), by default I went with a std::vector of std::vectors.
My guess is this can be done in one line I just don't know the correct syntax.
For example:
(1,2,5)
(9,3,6)
(7,8,4)
I thought it might be something like this -
vector<int> v1(1,2,3);
vector<int> v2(4,5,6);
vector<int> v3(7,8,9);
vector<vector<int>> vA(v1,v2,v3);
Normally, I wold read this info out of a text file, but I need to manually put in the numbers by hand and I have to use g++ 4.1.2

If you're not going to change the size or shape of this matrix and since you're hard-coding the values anyway, you may be better with a plain old array:
int matrix[][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
Otherwise, Fred Nurk's answer is what you are looking for.

The simplest way is the easiest (without C++0x):
vector<vector<int> > v (3);
for (int a = 0; a != 3; ++a) {
v[a].resize(3);
for (int b = 0; b != 3; ++b) {
v[a][b] = a * 3 + b + 1;
}
}
With 0x initializers, which I doubt that version of gcc supports:
vector<vector<int>> v = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

Related

Insert vector {x, y, z} into another vector?

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;
}

Generate all possible ordered subset from a set

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.

What is the best way to assign variables in a multidimensional vector using c++?

I have a matrix value like this
3 1 30
5 8 1
1 5 2
0 23 7
Currently I know only this way to assign variable to a multidimensional vector.
vector<vector <int> > vec;
vec[0][0]=3;
vec[0][1]=1;
vec[0][2]=30;
.
.
vec[3][2]=7;
For smaller matrix values this is ok but larger values this becomes harder. Is there any other way to assign variables in a multidimensional vectors.
EDIT
I am using codeblocks and I am getting this unusual error
#include<iostream>
#include<vector>
int main()
{
std::vector<std::vector<int> > vec = {{3,1,30},{5,8,1},{1,5,2},{0,23,7}};
return 0;
}
error
error: could not convert ‘{{3, 1, 30}, {5, 8, 1}, {1, 5, 2}, {0, 23, 7}}’ from ‘<brace-enclosed initializer list>’ to ‘std::vector<std::vector<int> >’
Use nested for loops: Example being:
for (int i = 0; i < MAX_VECTOR_SIZE; i++)
{
for(int j = 0; j < MAX_SUB_VECTOR_SIZE; j++)
{
vec[i][j] = value;
}
}
Don't forget to substitute your given values where necessary.
std::vector<std::vector<int>> array2d{
{3 , 1, 30},
{5, 8, 1},
{1 , 5, 2},
{0 , 23, 7}
};
You may do
const std::vector<std::vector<int>> v = {
{3, 1, 30},
{5, 8, 1},
{1, 5, 2},
{0, 23, 7}
};
It largely depends upon what you want to do - the "best" way is dependent upon your objective. But using the example given in your question, the most convenient way is via std::initializer_list construction:
std::vector<std::vector<int>> vec = {{3,1,30},{5,8,1},{1,5,2},{0,23,7}};
You can assign the single dimension vector first
vector<int> vec1 {3,1,30};
vector<int> vec2 {5,8,1};
vector<int> vec3 {1,5,2};
vector<int> vec4 {0,23,7};
And then assign the 2d vector
vector<vector<int>> vector2d;
vector2d.push_back(vec1);
vector2d.push_back(vec2);
vector2d.push_back(vec3);
vector2d.push_back(vec4);
If you use manual initialization as in you original code, be careful, you probably want to use vector's push_back instead of direct call to []: since your vector is still empty, access via [] will cause segmentation fault.
If you have C++11 use vector's constructor taking an (aggregate) initializer_list. This can be handy:
std::vector<std::vector <int> > vec;
vec = { {3, 1 , 30},
{5, 8 , 1 },
{1, 5 , 2 },
{0, 23, 7 } };
For more details see here. Here I assume your matrix is in Row-major order, i.e. each of the internal std::vector<int> represents a row of the matrix.
Finally, IMHO the easiest way is to use a linear algebra library like Eigen if you can. Eigen provides handy initialization methods: for example using << (see here for examples).
EDIT
For you compilation error: make sure that you enable at least C++11. If you use g++ add -std=c++11 to your compiler's tag.

How to filter vector elements relative to other ones?

I a vector of vectors, each representing a a set (in the mathematical sense). For example:
{{1, 3}, {4, 9, 14}, {1, 3}, {1, 4, 8, 9, 10, 14, 16}, {1, 3, 9}, {4, 9, 17, 22}}
I want to make the most efficient C++ possible function capable of filtering (in place, if possible) the vector in order to remove every item that contains another.
For example, here:
{1, 3} is contained by {1, 3} and {1, 3, 9}
{4, 9, 14} is contained by {1, 4, 8, 9, 10, 14, 16}
The resulting vector would then be:
{{1, 3}, {4, 9, 14}, {4, 9, 17, 22}}
As I'm beginning with C++ don't really have any clue of how to do this efficiently. I found, on other answers here, the erase / remove idiom, which doesn't seem to be very appropriate here, except by passing erase a closure as predicate. Which doesn't seem really idiomatic in C++.
Please note that keeping the original ordering doesn't matter, nor does the ordering of values inside each set.
Given what I learnt so far, thanks to your very helpful comments, the solution I came up with is:
struct std::vector<size_t> colset;
bool less_colsets(const colset& a, const colset& b) {
return a.size() < b.size();
}
void sort_colsets(std::list<colset>& l) {
l.sort(less_colsets);
}
void strip_subsets(std::list<colset>& l) {
sort_colsets(l);
for (std::list<colset>::iterator i = l.begin(); i != l.end(); ++i) {
std::list<colset>::iterator j = next(i, 1);
while (j != l.end()) {
if (includes((*j).begin(), (*j).end(), (*i).begin(), (*i).end())) {
j = l.erase(j);
}
else {
++j;
}
}
}
}
Note that I replaced the outermost std::vector by std::list which is much more optimised for element removal anywhere.
This seems to work as expected, though I'd need some more tests to prove this. The next step will be to use a more efficient comparison function than includes, which would take into account the fact that each vector is lexically ordered (which the program guarantees). I'll try this tomorrow.
Edit: Looks like std::includes already takes care of this fact. YAY!
Thanks everybody.

Initialize a 2 Dimensional vector<int> in CPP

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]));