storing a 2D array into a 2D vector in c++ - c++

Suppose I have a following 2D matrix in the following format. First line indicates the dimension and the rest other lines contains the elements. In this case it's a 6*6 Matrix:
6
1 2 3 4 2 3
3 3 4 5 2 1
4 3 3 1 2 3
5 4 3 6 2 1
3 2 4 3 4 3
2 3 4 1 5 6
Normally we can store the matrix in a vector using this:
typedef std::vector<int32_t> vec_1d;
typedef std::vector<vec_1d> vec_2d;
vec_2d array{
{ 1, 2, 3, 4, 2, 3 }
, { 3, 3, 4, 5, 2, 1 }
, { 4, 3, 3, 1, 2, 3 }
, { 5, 4, 3, 6, 2, 1 }
, { 3, 2, 4, 3, 4, 3 }
, { 2, 3, 4, 1, 5, 6 }
};
But if I want to take this array in the format I have shown above from a text file into a 2d vector like the above one, how will I do this in c++ ?

This should work:
#include "fstream"
#include "vector"
using namespace std;
int main()
{
ifstream fin("file.txt");
int n;
fin >> n;
vector < vector <int> > matrix (n, vector <int>(n));
// or vec_2d matrix (n, vec_1d(n)); with your typedefs
for (auto &i: matrix)
for (auto &j: i)
fin >> j;
}

Related

Cannot specify explicit initializer for arrays [SystemC]

Im using VS2013 along with the SystemC library from Allegro. I was trying to initialize two arrays as follows:
int pathObs1[19] = {10,9,8,7,6,5,4,3,2,1,2,3,4,5,6,7,8,9,10};
int Map[10][4] = {
{ 0, 3, 1, 4 }, //Grid 1
{ 1, 3, 2, 4 }, //Grid 2
{ 2, 3, 3, 4 }, //Grid 3
{ 3, 3, 4, 4 }, //Grid 4
{ 4, 3, 5, 4 }, //Grid 5
{ 5, 3, 6, 4 }, //Grid 6
{ 6, 3, 7, 4 }, //Grid 7
{ 6, 2, 7, 3 }, //Grid 8
{ 6, 1, 7, 2 }, //Grid 9
{ 6, 0, 7, 1 } //Grid 10
};
However i received the error the above error. I saw some questions on SO which had the same issue, however I dont think they were dealing with SystemC. Any easy workaround for this in SystemC since im trying to initialize inside my SC_MODULE header/constructor?
Edit: I had a typo in my array initialization. Still get the same error.
2dArray[m][n] means m rows n columns so you can keep n values in each row but in your code you defined matrix which had 3 columns but still you are assigning 4 values.
You can use a loop for filling the array:
#include <iostream>
#include <stdlib>
int main()
{
srand(time(null));
int map[10][4];
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 4; j++)
{
map[i][j] = rand(); // you can write smth like rand() % 5 to make a limit of the values
}
}
return 0;
}

How to create graph from vertex?

I have a list of connected vertexes.
My question is how to create and store a graph that represents this list?.
For example for
5
2 4 5
1 3 4
2 4 5
1 2 3 5
1 3 4
1 is connected to 2, 4, 5
2 -> 1, 3, 4
and so on..
Here is 2 (the same) representations.
And my second question is how to get all representations of that graph (in this image i showed 2, that are the same)
For one list of vertexes exists only one graphical represantation? if more, how to get all of that?
in image they are the same, differente drawings.
5 means how many lines
1 > 2, 4, 5
2 > 1, 3, 4
3 > 2, 4, 5
4 > 1, 2, 3, 5
5 > 1, 3, 4
(I am silly so I needed to type this in notepad).
#include <stdio.h>
class Cl_Graph;
class Cl_Chain;
class Cl_Vertex
{
friend Cl_Graph;
private:
Cl_Chain* mp_linkedTo;
Cl_Vertex();
void f_addLink(Cl_Vertex* in_link);
};
Cl_Vertex::Cl_Vertex()
{
mp_linkedTo= NULL;
}
class Cl_Graph
{
private:
int m_size;
Cl_Vertex* pm_vertexTable;
public:
Cl_Graph(int in_size);
void f_addLink(int in_index, int in_linkWith);
};
Cl_Graph::Cl_Graph(int in_size)
{
pm_vertexTable= new Cl_Vertex[m_size= in_size];
}
void Cl_Graph::f_addLink(int in_index, int in_linkWith)
{
if (in_index< m_size && in_linkWith< m_size)
{
pm_vertexTable[in_index].f_addLink(pm_vertexTable[in_linkWith]);
}
}
int main(int argc, char** argv)
{
Cl_Graph graph(5);
graph.f_addLink(1, 2);
graph.f_addLink(1, 4);
graph.f_addLink(1, 5);
// ...
return 0;
}
You can start with something like this. You can even type a function that would get a chain of vertexes as argument to add to graph, and instead of the array it can have a chain of link chains :p good luck!

Find the row sum of a matrix using CSR or COO storing format

I have for example the following matrix B which is stored in COO and CSR format (retrieved from the non-symetric example here). Could you please suggest an efficient c++ way to apply the matlab sum(B,2) function using the coo or csr(or both) storing format? Because it is quit possible to work with large arrays can we do that using parallel programming (omp or CUDA (e.g, thrust))?
Any algorithmic or library based suggestions are highly appreciated.
Thank you!
PS: Code to construct a sparse matrix and get the CSR coordinates can be found for example in the answer of this post.
COO format: CSR format:
row_index col_index value columns row_index value
1 1 1 0 0 1
1 2 -1 1 3 -1
1 3 -3 3 5 -3
2 1 -2 0 8 -2
2 2 5 1 11 5
3 3 4 2 13 4
3 4 6 3 6
3 5 4 4 4
4 1 -4 0 -4
4 3 2 2 2
4 4 7 3 7
5 2 8 1 8
5 5 -5 4 -5
For COO its pretty simple:
struct MatrixEntry {
size_t row;
size_t col;
int value;
};
std::vector<MatrixEntry> matrix = {
{ 1, 1, 1 },
{ 1, 2, -1 },
{ 1, 3, -3 },
{ 2, 1, -2 },
{ 2, 2, 5 },
{ 3, 3, 4 },
{ 3, 4, 6 },
{ 3, 5, 4 },
{ 4, 1, -4 },
{ 4, 3, 2 },
{ 4, 4, 7 },
{ 5, 2, 8 },
{ 5, 5, -5 },
};
std::vector<int> sum(5);
for (const auto& e : matrix) {
sum[e.row-1] += e.value;
}
and for large matrixes you can just split up the for loop into multiple smaller ranges and add the results at the end.
If you only need the sum of each row (and not columwise) CSR is also straight forward (and even more efficient):
std::vector<int> row_idx = { 0, 3, 5, 8, 11, 13 };
std::vector<int> value = { 1, -1, -3, -2, 5, 4, 6, 4, -4, 2, 7, 8, -5 };
std::vector<int> sum(5);
for(size_t i = 0; i < row_idx.size()-1; ++i) {
sum[i] = std::accumulate(value.begin() + row_idx[i], value.begin() + row_idx[i + 1], 0);
}
Again, for parallelism you can simply split up the loop.

Regarding vector values

Here is a code snippet below.
Input to program is
dimension d[] = {{4, 6, 7}, {1, 2, 3}, {4, 5, 6}, {10, 12, 32}};
PVecDim vecdim(new VecDim());
for (int i=0;i<sizeof(d)/sizeof(d[0]); ++i) {
vecdim->push_back(&d[i]);
}
getModList(vecdim);
Program:
class dimension;
typedef shared_ptr<vector<dimension*> > PVecDim;
typedef vector<dimension*> VecDim;
typedef vector<dimension*>::iterator VecDimIter;
struct dimension {
int height, width, length;
dimension(int h, int w, int l) : height(h), width(w), length(l) {
}
};
PVecDim getModList(PVecDim inList) {
PVecDim modList(new VecDim());
VecDimIter it;
for(it = inList->begin(); it!=inList->end(); ++it) {
dimension rot1((*it)->length, (*it)->width, (*it)->height);
dimension rot2((*it)->width, (*it)->height, (*it)->length);
cout<<"rot1 "<<rot1.height<<" "<<rot1.length<<" "<<rot1.width<<endl;
cout<<"rot2 "<<rot2.height<<" "<<rot2.length<<" "<<rot2.width<<endl;
modList->push_back(*it);
modList->push_back(&rot1);
modList->push_back(&rot2);
for(int i=0;i < 3;++i) {
cout<<(*modList)[i]->height<<" "<<(*modList)[i]->length<<" "<<(*modList)[i]->width<<" "<<endl;
}
}
return modList;
}
What I see is that the values rot1 and rot2 actually overwrite previous values.
For example that cout statement prints as below for input values defined at top. Can someone tell me why are these values being overwritten?
rot1 7 4 6
rot2 6 7 4
4 7 6
7 4 6
6 7 4
rot1 3 1 2
rot2 2 3 1
4 7 6
3 1 2
2 3 1
You are storing pointers to local variables when you do this kind of thing:
modList->push_back(&rot1);
These get invalidated every loop cycle. You could save yourself a lot of trouble by not storing pointers in the first place.

problrm with array in c++

this is my Stata.h
#include "State.h"
#include <iostream>
using namespace std;
class State
{
public:
int data[4][4];
int x;
int y;
int cost[];
State(void);
void CopyState(State*);
bool equals(State*);
int h(State*);
void print(void);
private:
int getLocation(State, int, int);
};
and this is my State.cpp
#include "State.h"
#include <iostream>
using namespace std;
State::State(void)
{
State::cost[] = {0, 3, 2, 5, 3, 4, 1, 2, 2, 1, 4, 3,
5, 2, 3, 2, 3, 0, 3, 2, 2, 3, 2, 1,
1, 2, 1, 4, 2, 3, 2, 3, 2, 3, 0, 3,
1, 2, 3, 2, 4, 1, 2, 1, 3, 2, 3, 2,
5, 2, 3 ,0 ,2 , 1 , 4 , 3 ,3 , 4 ,1 , 2,
2, 3, 2, 5, 3, 2, 1, 2, 0, 3, 2, 3,
3, 2, 1 ,2 ,2 , 1 ,4 ,3 , 4 ,3 ,2 , 1 ,
3 ,0, 3, 2, 2 , 3, 2, 1 , 1 , 2, 1, 4,
1 , 2, 3 ,4 ,2 ,3 ,0 ,3 ,1 , 2 ,3 ,2 ,
4 ,1, 2, 1, 2, 1, 2, 3, 3, 2, 3, 0,
2 ,1, 2 , 3 ,3 ,4 ,1 ,2 , 2 , 1 ,4 ,3,
3 , 2, 1, 2, 0 , 3 , 2 , 3, 3 , 2, 1, 2,
1 ,2, 1 , 4 ,2 ,3 ,2 , 1 , 3 , 0 , 3 , 2,
4 , 3, 2 , 1 , 4 , 1, 2 , 1 , 1 , 2, 3 , 2,
2, 3 ,0 ,3 ,1 , 2 , 3 , 4 , 3 ,4 , 1 ,2,
2 ,1, 2, 3 , 3 , 2 , 3 , 0, 2, 1, 2, 3,
5 , 2 ,3 , 2 ,2 ,1 , 4 ,3 ,3 ,4 ,1 ,2,
0 ,3, 2, 5, 2 , 3 , 2, 3, 1, 2, 1, 4,
2 ,3 ,2 , 1 ,3 , 0 ,3 , 2, 3 , 2 ,3 ,2 ,
4 ,1, 2, 1, 1 , 2, 3 , 2 , 2, 3 , 0, 3,
2 ,3 ,2 , 5 , 3 , 4 , 1 , 2 , 2 , 1 ,4 , 3 ,
5 , 2 ,3 ,0
};
}
void State::CopyState(State *state)
{
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
data[i][j] = state->data[i][j];
x = state->x;
y = state->y;
}
bool State::equals(State *state)
{
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
if (data[i][j] != state->data[i][j])
return false;
return true;
}
int State::h(State *state)
{
int k = 0;
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
{
int frmPos = 4 * i + j;
int toPos = getLocation(*state, i, j);
k += cost[16 * frmPos + toPos];
}
return k;
}
void State::print()
{
cout << "\n";
for (int i = 0; i < 4; i++)
{
cout << "\n";
for (int j = 0; j < 4; j++)
cout << data[i][j];
}
cout << endl;
}
the problem is in State.cpp in the constructor when I'm trying to assign values to the cost array I don't know where is the problem, please any one can solve that , sorry for my bad english
You can't do it that way. There's a couple of problems, but the first problem is this:
In the header you declare cost as an array with an unspecified size:
int cost[];
This isn't allowed in Standard C++ because now the compiler doesn't know how big the array is, and therefore doesn't know how big State will be. (Some compilers do allow it, but it's a special extension that won't work on other compilers.)
The simplest and often best way to do this is to use a vector:
#include <vector>
class State
{
// ...
std::vector <int> cost;
};
And then in the constructor:
State::State()
{
static const int startingValues [] =
{0, 3, 2, 5, 3, 4, 1, 2, 2, 1, 4, 3, ... };
static const size_t numStartingValues = sizeof (startingValues) / sizeof (startingValues [0]);
std::copy (startingValues, startingValues + numStartingValues, std::back_inserter (cost));
}
If you're using C++11, then this is made simpler with the uniform initialization syntax:
State::State()
:
cost {0, 3, 2, 5, ...}
{
}
First of all, the cost member is not an array, it is a pointer (or it was when I looked at it, but you've changed it. However, it's still not an array. It is now a compiler error.). If you want it to point to an array, first you have to allocate it. But that's a terrible idea. Change it to a vector:
class State {
...
std::vector<int> cost;
...
};
Then, in your constructor, you can initialize it like this (if your compiler supports C++11)
State::State() :
cost{0, 3, 2, 5, 3, 4} // trimmed for brevity, but you can put as many elements as you want
{}
If your compiler does not support C++11 (or does not support this feature), then you can initialize the vector like this:
State::State()
{
static int temp[] = {0, 3, 2, 5, 3, 4};
cost.assign(temp, temp + sizeof(temp) / sizeof(*temp));
}