I have been given the following code in a test.cpp file to implement:
cout << "Case 2: the non-static Transpose function" << endl;
{
double column[4] = {2, 1, 0, -1};
double row[3] = {2, 0, -1};
Matrix matrix = Matrix::Toeplitz(column, 4, row, 3);
cout << "The original Matrix = " << endl;
cout << matrix << endl; //This part of the code works
matrix.Transpose(); //How do I implement this?
cout << "The transposed version = " << endl;
cout << matrix << endl;
cout << "Press any key to continue ..." << flush;
system("read");
cout << endl;
}
The way Matrix::Toeplitz(column, 4, row, 3) works is as follows:
Matrix Matrix::Toeplitz(const double* column, const int noOfRows, const double* row, const int noOfColumns){
Matrix outT(column, noOfRows, row, noOfColumns);
return outT;
}
So how would I implement matrix.Transpose()? My code so far is as follows:
Matrix& Matrix::Transpose () {
double newrow[noOfRows];
for(int i=0; i<noOfRows; i++){
int index = GetIndex(i,0);
newrow[i] = data[index];
}
double newcol[noOfColumns];
for(int i=0; i<noOfColumns; i++){
int index = GetIndex(0,i);
newcol[i] = data[index];
}
Matrix outT(newcol, noOfColumns, newrow, noOfRows);
}
This has no effect on cout<<matrix<<endl;
I was thinking that Matrix outT(newcol, noOfColumns, newrow, noOfRows); should give new information (i.e. switching the column and row arrays) to the matrix object when implementing matrix.Transpose but it hasn't been working.
Is this the correct format Matrix& Matrix::Transpose () for implementing matrix.Transpose()?
Matrix::Transpose can't return a reference to a locally declared object. This will lead to many problems.
See C++ Returning reference to local variable.
It must return by copy (then, function can be const, as current object is not being modified):
Matrix Matrix::Transpose() const
{
double newrow[noOfRows];
for(int i=0; i<noOfRows; i++){
int index = GetIndex(i,0);
newrow[i] = data[index];
}
double newcol[noOfColumns];
for(int i=0; i<noOfColumns; i++){
int index = GetIndex(0,i);
newcol[i] = data[index];
}
return Matrix(newcol, noOfColumns, newrow, noOfRows);
}
Then, you use it this way:
Matrix transposed = matrix.Transpose(); // does not modify matrix object
cout << "The transposed version = " << endl;
cout << transposed << endl;
If returning Matrix&, you need to have your method transpose the current object and return it (return *this), only useful to help caller to chain many operators (like doing m.Transpose().Transpose() for instance).
Then, it could be (not tested):
Matrix& Matrix::Transpose()
{
// backup old content
double* backupData = new double[noOfRows*noOfColumns];
memcpy( backupData, data, sizeof(double)*noOfRows*noOfColumns );
// change matrix geometry
int oldRowCount = noOfRows;
noOfRows = noOfColumns;
noOfColumns = oldRowCount ;
// transpose matrix by copying from backup content
for ( unsigned int line = 0; line < noOfRows ; ++line )
{
for ( unsigned int col = line; col < noOfColumns; ++col )
{
data[line * noOfColumns + col] = backupData[col * noOfRows + line];
}
}
delete [] backupData;
return *this;
}
Then, you use it this way:
matrix.Transpose(); // modifies matrix object
cout << "The transposed version = " << endl;
cout << transposed << endl;
First off i know the multiplying part is wrong but i have some questions about the code.
1. When i am overloading my operator+ i print out the matrix using cout << *this then right after i return *this and when i do a+b on matix a and matix b it doesnt give me the same thing this is very confusing.
2. When i make matrix c down in my main i cant use my default constructor for some reason because when i go to set it = using my assignment operator overloaded function it gives me an error saying "expression must be a modifiable value. although using my constructor that sets the row and column numbers is the same as my default constructor using (0,0).
3. My assignment operator= function uses a copy constructor to make a new matrix using the values on the right hand side of the equal sign and when i print out c it doesn't give me anything
Any help would be great this is my hw for a algorithm class which i still need to do the algorithm for the multiplying matrices but i need to solve these issues first and im having a lot of trouble please help.
//Programmer: Eric Oudin
//Date: 10/21/2013
//Description: Working with matricies
#include <iostream>
using namespace std;
class matrixType
{
public:
friend ostream& operator<<(ostream&, const matrixType&);
const matrixType& operator*(const matrixType&);
matrixType& operator+(const matrixType&);
matrixType& operator-(const matrixType&);
const matrixType& operator=(const matrixType&);
void fillMatrix();
matrixType();
matrixType(int, int);
matrixType(const matrixType&);
~matrixType();
private:
int **matrix;
int rowSize;
int columnSize;
};
ostream& operator<< (ostream& osObject, const matrixType& matrix)
{
osObject << endl;
for (int i=0;i<matrix.rowSize;i++)
{
for (int j=0;j<matrix.columnSize;j++)
{
osObject << matrix.matrix[i][j] <<", ";
}
osObject << endl;
}
return osObject;
}
const matrixType& matrixType::operator=(const matrixType& matrixRight)
{
matrixType temp(matrixRight);
cout << temp;
return temp;
}
const matrixType& matrixType::operator*(const matrixType& matrixRight)
{
matrixType temp(rowSize*matrixRight.columnSize, columnSize*matrixRight.rowSize);
if(rowSize == matrixRight.columnSize)
{
for (int i=0;i<rowSize;i++)
{
for (int j=0;j<columnSize;j++)
{
temp.matrix[i][j] = matrix[i][j] * matrixRight.matrix[i][j];
}
}
}
else
{
cout << "Cannot multiply matricies that have different size rows from the others columns." << endl;
}
return temp;
}
matrixType& matrixType::operator+(const matrixType& matrixRight)
{
matrixType temp;
if(rowSize == matrixRight.rowSize && columnSize == matrixRight.columnSize)
{
temp.setRowsColumns(rowSize, columnSize);
for (int i=0;i<rowSize;i++)
{
for (int j=0;j<columnSize;j++)
{
temp.matrix[i][j] = matrix[i][j] + matrixRight.matrix[i][j];
}
}
}
else
{
cout << "Cannot add matricies that are different sizes." << endl;
}
return temp;
}
matrixType& matrixType::operator-(const matrixType& matrixRight)
{
matrixType temp(rowSize, columnSize);
if(rowSize == matrixRight.rowSize && columnSize == matrixRight.columnSize)
{
for (int i=0;i<rowSize;i++)
{
for (int j=0;j<columnSize;j++)
{
matrix[i][j] -= matrixRight.matrix[i][j];
}
}
}
else
{
cout << "Cannot subtract matricies that are different sizes." << endl;
}
return *this;
}
void matrixType::fillMatrix()
{
for (int i=0;i<rowSize;i++)
{
for (int j=0;j<columnSize;j++)
{
cout << "Enter the matix number at (" << i << "," << j << "):";
cin >> matrix[i][j];
}
}
}
matrixType::matrixType()
{
rowSize=0;
columnSize=0;
matrix = new int*[rowSize];
for (int i=0; i < rowSize; i++)
{
matrix[i] = new int[columnSize];
}
}
matrixType::matrixType(int setRows, int setColumns)
{
rowSize=setRows;
columnSize=setColumns;
matrix = new int*[rowSize];
for (int i=0; i < rowSize; i++)
{
matrix[i] = new int[columnSize];
}
}
matrixType::matrixType(const matrixType& otherMatrix)
{
rowSize=otherMatrix.rowSize;
columnSize=otherMatrix.columnSize;
matrix = new int*[rowSize];
for (int i = 0; i < rowSize; i++)
{
matrix[i]=new int[columnSize];
for (int j = 0; j < columnSize; j++)
{
matrix[i][j]=otherMatrix.matrix[i][j];
}
}
}
matrixType::~matrixType()
{
delete [] matrix;
}
int main()
{
matrixType a(2,2);
matrixType b(2,2);
matrixType c(0,0);
cout << "fill matrix a:"<< endl;;
a.fillMatrix();
cout << "fill matrix b:"<< endl;;
b.fillMatrix();
cout << a;
cout << b;
//c = a+b;
cout <<"matrix a + matrix b =" << a+b;
system("PAUSE");
return 0;
}
EDIT:
still having trouble with things not returning what i am telling it to return
This code doesn't do what you think it does:
for (int j = 0; j < columnSize; j++)
{
matrix[i]=new int[columnSize];
matrix[i][j]=otherMatrix.matrix[i][j];
}
It allocates a column, then copies the first value. Then it allocates another column (forgetting about the old column), and copies the second value. Then it allocates another column (forgetting about the old column again), and copies the third value.
I hope the problem is clear from that description alone.
Are you trying to use matrixType c();? That would declare a function. The correct syntax to use the default constructor would be matrixType c;
Your operator= doesn't actually assign anything. So c = a+b; calculates a+b but doesn't change c.
I have a 3D string vector in C++:
vector<vector<vector<string>>> some_vector
That I am trying is to find a fast method to allocate memory for it.
I tried to define it with two different methods as follow:
#include<vector>
#include<iostream>
#include<ctime>
using namespace std;
#define DIM1 100
#define DIM2 9
#define DIM3 120
int main()
{
clock_t t1_start = clock();
vector<vector<vector<string>>> vec1(DIM1, vector<vector<string>>(DIM2, vector<string>(DIM3)));
clock_t t1_end = clock();
double diff1 = (t1_end - t1_start) / double(CLOCKS_PER_SEC);
clock_t t2_start = clock();
vector<vector<vector<string>>> vec2;
vec2.resize(DIM1);
for(int i = 0; i < DIM1; i++)
{
vec2[i].resize(DIM2);
for(int j = 0; j < DIM2; j++)
vec2[i][j].resize(DIM3);
}
clock_t t2_end = clock();
double diff2 = (t2_end - t2_start) / double(CLOCKS_PER_SEC);
cout<<"1st definition used time: "<<diff1<<"s"<<endl;
cout<<"2nd definition used time: "<<diff2<<"s"<<endl;
}
I expect that the first method (vec1) could be faster than the 2nd one (vec2).
But it turned out that the 1st method is much slower than the 2nd. On my machine, the 1st method used 0.245 seconds, while the 2nd method used 0.152 seconds.
Moreover, when I switch the data type to int, the 1st one took 0.058 second, and the 2nd took 0.004.
May I know what cause such difference? And is there better way to allocate memory for a 3D vector?
Many thanks in advance.
May I know what cause such difference?
The first version constructs a 2-d vector by copying a 1-d vector, and then constructs the 3-d vector by copying that. This might be slower than resizing the vectors without copying. However, I'd hope that the difference would be negligible if you're building with optimisation.
And is there better way to allocate memory for a 3D vector?
It might be better to use a single contiguous array, wrapped in a class that provides multi-dimensional accessors. This would make allocation much simpler, and would also avoid some pointer dereferencing when accessing elements (at the cost of a bit of arithmetic). Something like this:
template <typename T>
class vector3d {
public:
vector3d(size_t d1=0, size_t d2=0, size_t d3=0, T const & t=T()) :
d1(d1), d2(d2), d3(d3), data(d1*d2*d3, t)
{}
T & operator()(size_t i, size_t j, size_t k) {
return data[i*d2*d3 + j*d3 + k];
}
T const & operator()(size_t i, size_t j, size_t k) const {
return data[i*d2*d3 + j*d3 + k];
}
private:
size_t d1,d2,d3;
std::vector<T> data;
};
I think I'd optimize it by allocating one large block of memory instead of a lot of little ones. This one is only 2D instead of 3D, but gives the basic idea:
template <class T>
class matrix {
size_t columns_;
std::vector<T> data;
public:
matrix(size_t columns, size_t rows) : columns_(columns), data(columns*rows) {}
T &operator()(size_t column, size_t row) { return data[row*columns_+column]; }
};
For 3D, you'll need to deal with "planes" (or something) along with rows and columns, but the basic idea is pretty much the same.
I added several features to Mike Seymour's code such as dynamically resize the 3d vector and on access/assign bounds checking for data vector.
template <typename T>
class vector3d
{
public:
vector3d(size_t d1=0, size_t d2=0, size_t d3=0, T const & t=T()) :
d1(d1), d2(d2), d3(d3), data(d1*d2*d3, t)
{}
T & operator()(size_t i, size_t j, size_t k)
{
return (i<=d1 && j<=d2 && k<=d3) ? data[i*d2*d3 + j*d3 + k]
: data.at(i*d2*d3 + j*d3 + k);
}
T const & operator()(size_t i, size_t j, size_t k) const
{
return data[i*d2*d3 + j*d3 + k];
}
void resize(const size_t _d1=0, const size_t _d2=0, const size_t _d3=0)
{
data.resize(_d1*_d2*_d3);
d1=_d1;
d2=_d2;
d3=_d3;
}
void shrink_to_fit()
{
data.shrink_to_fit();
}
const size_t length() const
{
return data.size();
}
const size_t capacity() const
{
return data.capacity();
}
const size_t x() const
{
return d1;
}
const size_t y() const
{
return d2;
}
const size_t z() const
{
return d3;
}
private:
size_t d1,d2,d3;
std::vector<T> data;
};
Usage:
vector3d<int> vec3d(2,2,2,31); //create 2x2x2 3d vector and fill it with 31
vec3d(1,1,2)=45; //assign 45 at vec3d(1,1,2)
vec3d.resize(2,2,1); //resize the vec3d to 2x2x1
vec3d(1,2,2)=67; //error (its out of bounds)
To initialize a 3D string vector you shall initialize the vector structure for each dimension one at a time and for each index, for instance:
vector<vector<vector<string> > > myvector; //declare the 3D vector
for(k=0; k<3; k++)
{
myvector.push_back(vector<vector<string> >()); //initialize the first index with a 2D vector
for(i=0; i<4; i++)
{
myvector[k].push_back(vector<string>()); //initialize the 2 index with a row of strings
for(j=0; j<4; j++)
{
result = " whatever you want to insert in the vector element";
myvector[k][i].push_back(result); //fulfill the last index regularly
}
}
}
When you initialize a vector of vectors in the first method, a temporary vector is allocated and then copied into the outer vector the required number of times. This means you have an extra allocation that is unnecessary and the new elements are initialized by copying their value from another data structure, which uses more memory accesses.
Resizing the vectors as per the second method is more ugly but avoids the extra allocation. Furthermore the new elements are created by the default constructor and do not need to copy from other vectors. This will also be faster.
If speed matters (and maybe it doesn't, premature optimization and all that), then you must use the second method (OR a single-block allocation as suggested by the other answers). I don't have faith that a compiler can simply "optimize" away the inefficiency of the first method.
Here is an example of various dimensions of vectors in case anyone out there cares. I know when I was starting out it was a pain to find how to give initial values to multidimension vectors as I couldn't find any examples;
// This simple project demonstrates a single vector, a 2D vector, a 3D vector and a 4D vector in C++
//
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
vector<int> myVector = { 0,1,2,3,4,5,6 };
vector<vector<int>> my2dVector = { {1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20},{21,22,23,24,25},{0,-1,-2,-3,-4},{-6,7,22,-15,-25},{true,true,false,true,false} };
vector < vector < vector<int>>> my3dVector =
{
{
{1,2,3},
{4,5,6}, // plane 0
{7,8,9}
},
{
{-1,-2,-3},
{-4,-5,-6}, // plane 1
{-10,-22,36}
},
{
{129,212,999},
{0,0,1}, // plane 2
{false,true,false}
}
};
vector<vector<vector<vector<int>>>> my4dVector =
{
{ //Cube 0
{
{1,2,3},
{4,5,6}, // plane 0
{7,8,9}
},
{
{-1,-2,-3},
{-4,-5,-6}, // plane 1
{-10,-22,36}
},
{
{129,212,999},
{0,0,1}, // plane 2
{false,true,false}
}
},
{ //Cube 1
{
{10,2,-9},
{44,55,60}, // plane 0
{71,85,99}
},
{
{-561,-6562,-453},
{-14,-55,-76}, // plane 1
{-110,-212,316}
},
{
{729,812,456},
{40,10,17}, // plane 2
{true,true,false}
}
}
};
// 1D VECTOR..............
cout << "This is a 1D vector of size " << myVector.size () << "\n";
for (int i = 0; i < myVector.size (); i++)
{
cout << myVector[i] << "\t";
}
cout << "\n\n";
// 2D VECTOR..............
cout << "This is a 2D vector of size " << my2dVector.size () << " X " << my2dVector[0].size () << ".";
if (my2dVector.size () == my2dVector[0].size ()) cout << " This is a square matrix.";
cout << "\n ";
for (int i = 0; i < my2dVector[0].size (); i++)
{
cout << "C" << i << "\t";
}
cout << endl;
for (int i = 0; i < my2dVector.size (); i++)
{
cout << "Row: " << i << " -> ";
for (int j = 0; j < my2dVector[i].size (); j++)
{
if (my2dVector[i][j] >= 0 && my2dVector[i][j] <= 9) cout << " ";
cout << my2dVector[i][j] << "\t";
}
cout << endl;
}
cout << "\n\n";
// 3D VECTOR.................
cout << "This is a 3D vector of size " << my3dVector[0].size () << " X " << my3dVector[0][0].size () << " with " << my3dVector.size () << " planes.\n";
for (int i = 0; i < my3dVector.size (); i++)
{
cout << "Plane #" << i << "\n";
for (int j = 0; j < my3dVector[i].size (); j++)
{
for (int k = 0; k < my3dVector[i][j].size (); k++)
{
cout << my3dVector[i][j][k] << "\t";
}
cout << "\n";
}
}
cout << "\n\n";
//4D VECTOR.................
cout << "This is a 4D vector of size " << my4dVector[0][0].size () << " X " << my4dVector[0][0][0].size () << " with " << my4dVector[0].size () << " planes and " << my4dVector.size () << " cubes.\n";
for (int i = 0; i < my4dVector.size (); i++)
{
cout << "\nCUBE #"<< i<< " _________________\n";
for (int j = 0; j < my4dVector[i].size (); j++)
{
cout << "Plane #" << j << " |\n";
for (int k = 0; k < my4dVector[i][j].size (); k++)
{
for (int l = 0; l < my4dVector[i][j][k].size (); l++)
{
cout << my4dVector[i][j][k][l] << "\t";
}
cout << "|\n";
}
cout << "________________________|\n";
}
cout << "\n";
}
}
I am currently working on a project implementing a templated matrix class; however, whenever I try to run my test function, the program crashes and core dumps. The following is the output I get:
0 0
[3 3 1 2 3 4 5 6 9 8 10]
[1 2 3
4 5 6
9 8 10]
stream out sucessInvalid Input for matrix
stream in sucessError: matrix Multiplication not defined.
[1 2 3
4 5 6
9 8 10]
Error: The addition of two matrices of different demensions is not defined.
Error: The addition of two matrices of different demensions is not defined.
7700640
7700576
Error: The addition of two matrices of different demensions is not defined.
*** glibc detected *** ./a.out: free(): invalid pointer: 0x00000030143b0778 ***
======= Backtrace: ========= <Continues> ...
The Calling function is:
TestingMatrix(){
matrix<int> a, b, c;
//Three empty matrices are created
cout << a.numrows() << " " << a.numcols() << endl; // yields 0 0
cin >> a; // User types [3 3 1 2 3 6 5 4 9 8 10]
// This will create a 3 by 3 matrix
cout << a;
cin >> b; //User types [3 2 9 1 2 3 4 5]
cout << b;
c=a*b;
cout << c << endl;
cout << b+c << endl;
matrix<int> d(5*b); // d is initialized to 5*b
cout << d << endl;
cout << a[0][0] << endl;
//Should printout 1
cout << a[1][2] << endl;
//Should printout 4
d = a + b;
//This should cause an exception that you
//are able to handle; The sizes of a and b don’t agree.
}//End of TestingMatrix() function
The matrix class is as follows:
// matrix.h
#ifndef matrix_H
#define matrix_H
#include <iostream>
#include <cstdlib>
using namespace std;
template <class mType> class matrix {
public:
matrix() : N(0), M(0), origin(NULL) { /* EMPTY */ }
matrix(int n, int m): N(n), M(m), origin(NULL) {
allocate(n,m);
}
~matrix() {
clear();
}
matrix & operator=(const matrix &rhs) {
if (this != &rhs) { //Check to see they're not the same instance
this->clear();
this->allocate(rhs.numrows(), rhs.numcols());
for(int i=0; i<N; ++i)
for (int j=0; j<M; ++j)
this->origin[i][j] = rhs[i][j];
}
return *this;
}
matrix & operator+=(const matrix &rhs) {
try {
if ( this->numrows() != rhs.numrows() ||
this->numcols() != rhs.numcols() )
throw 1;
}
catch (int e)
{
cerr << "Error: The addition of two matrices of different demensions is not defined." << endl;
return *this;
}
for(int i=0; i<N; ++i)
for (int j=0; j<M; ++j)
this->origin[i][j] += rhs[i][j];
return *this;
}
const matrix operator+(const matrix &rhs) const {
matrix tmp = *this; // tmp copy so we can use the += operator
return (tmp += rhs); // return answer
}
const matrix operator*(const matrix &rhs) const {
try {
if ( this->numcols() != rhs.numrows() )
throw 1;
}
catch (int e)
{
cerr << "Error: matrix Multiplication not defined." << endl;
return *this;
}
matrix<mType> returnmatrix(this->numrows(), rhs.numcols());
for (int i=0; i<returnmatrix.numrows(); ++i)
for (int j=0; j<returnmatrix.numcols(); ++j)
for (int k=0; k < this->numcols(); ++k)
returnmatrix[i][j] += *this[i][k] * rhs[k][j];
return returnmatrix;
}
inline int const numrows() const {
return N;
}
inline int const numcols() const {
return M;
}
void allocate(int n, int m) {
if (origin)
clear();
origin = new mType* [n];
for (int i=0; i<n; ++i)
origin[i] = new mType[m];
M=m;
N=n;
}
void clear() {
if (origin) {
for(int i = 0; i < N; i++)
delete[] origin[i];
delete origin;
}
M=N=0; // Reset
origin=NULL;
}
mType* operator [] (const int index) { return origin[index]; }
const mType* operator [] (const int index) const { return origin[index]; }
friend matrix<mType> operator*( mType factor, const matrix<mType> rhs ) {
matrix<mType> out(rhs.numrows() , rhs.numcols());
for (int i=0; i<rhs.numrows(); ++i) {
for (int j=0; j<rhs.numcols(); ++j) {
out[i][j] = rhs[i][j]*factor;
}
}
return out;
}
friend ostream& operator<< (ostream& out, const matrix<mType>& A) {
if (A.numrows() > 0 && 0 < A.numcols()) {
out <<"[";
for (int j=0; j<A.numcols(); ++j) {
out << A[0][j] << " ";
}
for (int i=1; i<A.numrows(); ++i) {
out << endl;
for (int j=0; j<A.numcols(); ++j) {
out << " " << A[i][j];
}
}
out << "]" <<endl;
}
return out;
}
friend istream& operator>> (istream& in, matrix<mType> &A) {
//[3 2 9 1 2 3 4 5]
//toss first char
try {
if (in.get() != '[')
throw 1;
int N, M;
mType tmp;
in >> N;
in >> M;
A = matrix<mType>(N,M);
for (int i=0; i<N; ++i)
for (int j = 0; j < M; j++)
{
in >> tmp;
A[i][j] = tmp;
}
in.get();
}
catch (int e) {
cerr << "Invalid Input for matrix" << endl;
}
return in;
}
private:
int N, M;
mType ** origin;
};
#endif
Does anyone have any idea as to how resolve this? I'm pretty lost as to the source fo this issue.
Thanks in advance.
Since you have dynamically allocated resources, you should follow the rule of three and implement a copy constructor. Currently a copy construction will use the compiler generated copy constructor, making a copy of the pointer to the underlying data, without copying the data itself.
There is at least one copy construction in your addition operator:
const matrix operator+(const matrix &rhs) const {
matrix tmp = *this; // copy!
return (tmp += rhs); // potentially another copy
}
You have no copy c-tor and compiler will generate default, which does memberwise-copy, but if you have dynamically allocated resources in class - you should have your own copy c-tor, that do deep-copy.
I am trying to take in an input for the dimensions of a 2D matrix. And then use user input to fill in this matrix. The way I tried doing this is via vectors (vectors of vectors). But I have encountered some errors whenever I try to read in data and append it to the matrix.
//cin>>CC; cin>>RR; already done
vector<vector<int> > matrix;
for(int i = 0; i<RR; i++)
{
for(int j = 0; j<CC; j++)
{
cout<<"Enter the number for Matrix 1";
cin>>matrix[i][j];
}
}
Whenever I try to do this, it gives me a subscript out of range error. Any advice?
You have to initialize the vector of vectors to the appropriate size before accessing any elements. You can do it like this:
// assumes using std::vector for brevity
vector<vector<int>> matrix(RR, vector<int>(CC));
This creates a vector of RR size CC vectors, filled with 0.
As it is, both dimensions of your vector are 0.
Instead, initialize the vector as this:
vector<vector<int> > matrix(RR);
for ( int i = 0 ; i < RR ; i++ )
matrix[i].resize(CC);
This will give you a matrix of dimensions RR * CC with all elements set to 0.
I'm not familiar with c++, but a quick look at the documentation suggests that this should work:
//cin>>CC; cin>>RR; already done
vector<vector<int> > matrix;
for(int i = 0; i<RR; i++)
{
vector<int> myvector;
for(int j = 0; j<CC; j++)
{
int tempVal = 0;
cout<<"Enter the number for Matrix 1";
cin>>tempVal;
myvector.push_back(tempVal);
}
matrix.push_back(myvector);
}
Assume we have the following class:
#include <vector>
class Matrix {
private:
std::vector<std::vector<int>> data;
};
First of all I would like suggest you to implement a default constructor:
#include <vector>
class Matrix {
public:
Matrix(): data({}) {}
private:
std::vector<std::vector<int>> data;
};
At this time we can create Matrix instance as follows:
Matrix one;
The next strategic step is to implement a Reset method, which takes two integer parameters that specify the new number of rows and columns of the matrix, respectively:
#include <vector>
class Matrix {
public:
Matrix(): data({}) {}
Matrix(const int &rows, const int &cols) {
Reset(rows, cols);
}
void Reset(const int &rows, const int &cols) {
if (rows == 0 || cols == 0) {
data.assign(0, std::vector<int>(0));
} else {
data.assign(rows, std::vector<int>(cols));
}
}
private:
std::vector<std::vector<int>> data;
};
At this time the Reset method changes the dimensions of the 2D-matrix to the given ones and resets all its elements. Let me show you a bit later why we may need this.
Well, we can create and initialize our matrix:
Matrix two(3, 5);
Lets add info methods for our matrix:
#include <vector>
class Matrix {
public:
Matrix(): data({}) {}
Matrix(const int &rows, const int &cols) {
Reset(rows, cols);
}
void Reset(const int &rows, const int &cols) {
data.resize(rows);
for (int i = 0; i < rows; ++i) {
data.at(i).resize(cols);
}
}
int GetNumRows() const {
return data.size();
}
int GetNumColumns() const {
if (GetNumRows() > 0) {
return data[0].size();
}
return 0;
}
private:
std::vector<std::vector<int>> data;
};
At this time we can get some trivial matrix debug info:
#include <iostream>
void MatrixInfo(const Matrix& m) {
std::cout << "{ \"rows\": " << m.GetNumRows()
<< ", \"cols\": " << m.GetNumColumns() << " }" << std::endl;
}
int main() {
Matrix three(3, 4);
MatrixInfo(three);
}
The second class method we need at this time is At. A sort of getter for our private data:
#include <vector>
class Matrix {
public:
Matrix(): data({}) {}
Matrix(const int &rows, const int &cols) {
Reset(rows, cols);
}
void Reset(const int &rows, const int &cols) {
data.resize(rows);
for (int i = 0; i < rows; ++i) {
data.at(i).resize(cols);
}
}
int At(const int &row, const int &col) const {
return data.at(row).at(col);
}
int& At(const int &row, const int &col) {
return data.at(row).at(col);
}
int GetNumRows() const {
return data.size();
}
int GetNumColumns() const {
if (GetNumRows() > 0) {
return data[0].size();
}
return 0;
}
private:
std::vector<std::vector<int>> data;
};
The constant At method takes the row number and column number and returns the value in the corresponding matrix cell:
#include <iostream>
int main() {
Matrix three(3, 4);
std::cout << three.At(1, 2); // 0 at this time
}
The second, non-constant At method with the same parameters returns a reference to the value in the corresponding matrix cell:
#include <iostream>
int main() {
Matrix three(3, 4);
three.At(1, 2) = 8;
std::cout << three.At(1, 2); // 8
}
Finally lets implement >> operator:
#include <iostream>
std::istream& operator>>(std::istream& stream, Matrix &matrix) {
int row = 0, col = 0;
stream >> row >> col;
matrix.Reset(row, col);
for (int r = 0; r < row; ++r) {
for (int c = 0; c < col; ++c) {
stream >> matrix.At(r, c);
}
}
return stream;
}
And test it:
#include <iostream>
int main() {
Matrix four; // An empty matrix
MatrixInfo(four);
// Example output:
//
// { "rows": 0, "cols": 0 }
std::cin >> four;
// Example input
//
// 2 3
// 4 -1 10
// 8 7 13
MatrixInfo(four);
// Example output:
//
// { "rows": 2, "cols": 3 }
}
Feel free to add out of range check. I hope this example helps you :)
try this. m = row, n = col
vector<vector<int>> matrix(m, vector<int>(n));
for(i = 0;i < m; i++)
{
for(j = 0; j < n; j++)
{
cin >> matrix[i][j];
}
cout << endl;
}
cout << "::matrix::" << endl;
for(i = 0; i < m; i++)
{
for(j = 0; j < n; j++)
{
cout << matrix[i][j] << " ";
}
cout << endl;
}
Vector needs to be initialized before using it as cin>>v[i][j]. Even if it was 1D vector, it still needs an initialization, see this link
After initialization there will be no errors, see this link
What you have initialized is a vector of vectors, so you definitely have to include a vector to be inserted("Pushed" in the terminology of vectors) in the original vector you have named matrix in your example.
One more thing, you cannot directly insert values in the vector using the operator "cin". Use a variable which takes input and then insert the same in the vector.
Please try this out :
int num;
for(int i=0; i<RR; i++){
vector<int>inter_mat; //Intermediate matrix to help insert(push) contents of whole row at a time
for(int j=0; j<CC; j++){
cin>>num; //Extra variable in helping push our number to vector
vin.push_back(num); //Inserting numbers in a row, one by one
}
v.push_back(vin); //Inserting the whole row at once to original 2D matrix
}
I did this class for that purpose. it produces a variable size matrix ( expandable) when more items are added
'''
#pragma once
#include<vector>
#include<iostream>
#include<iomanip>
using namespace std;
template <class T>class Matrix
{
public:
Matrix() = default;
bool AddItem(unsigned r, unsigned c, T value)
{
if (r >= Rows_count)
{
Rows.resize(r + 1);
Rows_count = r + 1;
}
else
{
Rows.resize(Rows_count);
}
if (c >= Columns_Count )
{
for (std::vector<T>& row : Rows)
{
row.resize(c + 1);
}
Columns_Count = c + 1;
}
else
{
for (std::vector<T>& row : Rows)
{
row.resize(Columns_Count);
}
}
if (r < Rows.size())
if (c < static_cast<std::vector<T>>(Rows.at(r)).size())
{
(Rows.at(r)).at(c) = value;
}
else
{
cout << Rows.at(r).size() << " greater than " << c << endl;
}
else
cout << "ERROR" << endl;
return true;
}
void Show()
{
std::cout << "*****************"<<std::endl;
for (std::vector<T> r : Rows)
{
for (auto& c : r)
std::cout << " " <<setw(5)<< c;
std::cout << std::endl;
}
std::cout << "*****************" << std::endl;
}
void Show(size_t n)
{
std::cout << "*****************" << std::endl;
for (std::vector<T> r : Rows)
{
for (auto& c : r)
std::cout << " " << setw(n) << c;
std::cout << std::endl;
}
std::cout << "*****************" << std::endl;
}
// ~Matrix();
public:
std::vector<std::vector<T>> Rows;
unsigned Rows_count;
unsigned Columns_Count;
};
'''