How to pass matrix and int into a class method as parameters? - c++

int main(){
int row1, column1;
cout << "How many rows for first matrix?";
cin >> row1;
cout << "How many columns first matrix?";
cin >> column1;
int org[row1][column1];
cout << "Enter the elements of first matrix: ";
for(int i=0;i<row1;i++){
for(int j=0;j<column1;j++){
cin>>org[i][j];
}
}
for(int i=0;i<row1;i++){
for(int j=0;j<column1;j++){
cout<<org[i][j];
}
cout<<endl;
}
matrixreshape sol;
I have problems passing column1, row1, and matrix org into the matrixReshape function.
cout<<sol.matrixReshape(vector<vector<int> org[row1][column1],row1, column1);
matrixReshape function as follows:
class matrixreshape {
public:
vector<vector<int>> matrixReshape(vector<vector<int>>& nums, int r, int c) {
vector<vector<int>> newMatrix(r, vector<int>(c, 0));

The method matrixReshape needs a vector<vector<int>> as an actual argument. You are trying to pass it a 2D VLA which is not directly convertible.
You need to use vector<vector<int>> for input and pass that to the matrixReshape.
Here's an example:
vector<vector<int>> org( row1 );
for ( int i = 0; i < org.size(); i++ )
{
org[i].resize( column1 );
for ( int j = 0; j < org[i].size(); j++ )
{
cin >> org[i][j];
}
}
// and then pass it
matrixreshape sol;
cout << sol.matrixReshape( org, row1, col1 );
Or, with C++11's range-for loop, it would be like this:
std::size_t rows {0};
std::size_t cols {0};
std::cin >> rows >> cols;
std::vector<std::vector<int>> matrix( rows );
for ( auto& r : matrix )
{
r.resize( cols );
for ( auto& c : r )
{
std::cin >> c;
}
}
matrixreshape sol;
std::cout << sol.matrixReshape( matrix, rows, cols );
Here's a complete working example: https://godbolt.org/z/XPwRMq
In addition, you don't need rows and columns information to pass to matrixReshape() method as the std::vector has size() method. You can use that if you need that.
Another thing is that you have to overload stream insertion operator << for this type to print it with std::cout.
Here's an example (live):
#include <iostream>
#include <vector>
using Matrix = std::vector<std::vector<int>>;
std::ostream& operator<<( std::ostream& os, const Matrix& m )
{
for ( const auto& r : m )
{
for ( const auto& c : r )
{
os << c << ' ';
}
os << '\n';
}
return os;
}
int main()
{
const Matrix m
{
{ 1, 2 },
{ 3, 4 }
};
std::cout << m;
return 0;
}
Output:
1 2
3 4

Related

Multiplication of a vector and a matrix in c++

I tried to multiply a vector by a matrix but I can't get it to work because the loop always stops at one line. But with no error code, I've tried different ways to write the code into the resulting vector but it doesn't work. The outputs are to control where the loop stops, it stops after res[i] += (A[i][k] * B[k]);.
This is the specific function to perform the vector & matrix multiplication, if you need all the code let me know.
void vector_matrix_multiplication(vector<vector<int>> A,vector<int> B, int col1, int row1, int row2, vector<int>& res) {
int row = row1;
if(row1 < row2)
row = row2;
for(int i = 0; i < row; i++) {
cout << "Loop 1 ";
cout << i << endl;
for (int k = 0; k < col1; k++) {
cout << "Loop 2 " << i << " " << k << endl;
res[i] += (A[i][k] * B[k]);
cout << "Loop 2?" << endl;
}
}
The output of the function (with input A = {{2,3},{4,5}} & B = {1,2} is:
Loop 1 0
Loop 2 0 0
#include <iostream>
#include <vector>
using namespace std;
void vectorinput(vector<int>& a, int col){
cout << "Vector: " << endl;
for(int i = 0; i < col; i++) {
int x;
cin >> x;
a.push_back(x);
}
}
void matrixinput(vector<vector<int>>& a, int row, int col){
cout << "Matrix: " << endl;
for(int i = 0; i < row; i++) {
vector<int> vector;
for(int j = 0; j < col; j++) {
int x;
cin >> x;
vector.push_back(x);
}
a.push_back(vector);
}
}
int main(){
vector<int> vector;
vector<vector<int>> matrix; //Matrix is read in separate function
int row1 = 0; //Number of rows of first matrix
int col1 = 0; //Number of columns of first matrix
int row2 = 0; //Number of rows second matrix (redundant in this case)
int col2 = 0; //Number of columns second matrix
matrixinput(matrix1, row1, col1);
vectorinput(vector2, col2);
int row = row1; //Matrix with number of columns "col1", rows "row" - in this case both are 2
if(row2 > row1)
row = row2; //Vector with number of rows "row2" - in this case 2
vector<int> resvector(row, col1);
vector_matrix_multiplication(matrix2, vector1, col2, row, col1, resvector);
for(int i = 0; i < row; i++) {
cout << resvector[i] << endl;
}
return 0;
}
I hope this clarifies the purpose of the program and the function. I tried to cut it down a little because I have a lot of useless code in it. (Plus I struggled to input the code at first, was not quite sure how the code block works - sorry ^^)
There are following three bugs in your code:
Since you use the following ctor of std::vector
explicit vector(size_type count,
const T& value = T(),
const Allocator& alloc = Allocator());
, the second argument of resvector must be zero.
row1, row2, col1 and col2 are all zero through the main function and thus the loop in vector_matrix_multiplication does not work.
We can also reduce these variables to row and col of the matrix as #n.m. suggests in the comments.
matrix1, matrix2, vector1 and vector2 are not defined.
In summary, the following minimally fixed version will work fine for you:
int main()
{
std::vector<int> vec;
std::vector<std::vector<int>> mat;
int row = 2; //Number of rows of matrix
int col = 2; //Number of columns of matrix
matrixinput(mat, row, col);
vectorinput(vec, col);
std::vector<int> resvector(row, 0);
// 5th argument is redundant as #n.m. suggested
vector_matrix_multiplication(mat, vec, col, row, col, resvector);
for(int i = 0; i < row; i++) {
std::cout << resvector[i] << std::endl;
}
return 0;
}
and welcome to StackOverflow! I suggest you using mathematical libraries for this kind of stuff. The reason is:
they are already tested by someone else
they are efficient and optimized to use advanced CPU features
they are easier to use
I've used two different libraries: glm and Eigen
If you want to build your own library for learning purpose I suggest you looking how these libraries are written (they're open source)

2D vector of unknown size

I defined an empty vector of vectors :
vector< vector<int> > v;
How do i fill that empty vector with vector of size 2 integers ( from input ) each iteration of while loop?
while ( cin >> x >> y ) {
//....
}
Will this one work? Or what's the best and most elegant / effective way of doing it?
while ( cin >> x >> y )
{
vector<int> row;
row.push_back( x );
row.push_back( y );
v.push_back( row );
}
As pointed out by JerryCoffin, you probably better use a :
struct Point {
int x;
int y;
};
and then you might overload the output operator
std::ostream& operator<< (std::ostream& o,const Point& xy){
o << xy.x << " " << xy.y;
return o;
}
and similar the input operator (see e.g. here). And then you can use it like this:
int main() {
Point xy;
std::vector<Point> v;
v.push_back(xy);
std::cout << v[0] << std::endl;
return 0;
}
The another way of doing so is to push the value in a 1-D vector and then push that 1-D vector in 2-D vector. I have also printed the values as a test.
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t,n,temp;
cin>>t;
vector<vector<int>> value;
for(int i=0;i<t;i++)
{
cin>>n;
vector<int> x;
for(int j=0;j<n;j++)
{
cin>>temp;
x.push_back(temp);
}
value.push_back(x);
}
for(int i=0;i<t;i++)
{
for(int j=0;j<value[i].size();j++)
{
cout<<value[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
Hope it helps!!
I wrote it - compilator didnt say anything but i have never used vectors so i haven't figured out how to print it yet
You can print using for example a range based for loop (C++11):
for (const auto &vec : v) { // for every vector in v
for (const auto &num : vec) // print the numbers
cout << num << " ";
cout << '\n';
}
And regular for loop:
for (unsigned int i = 0; i != v.size(); ++i) {
for (unsigned int j = 0; j != v[i].size(); ++j) {
cout << v[i][j] << " ";
}
cout << '\n';
}

C++ program to read a csv matrix and print the transpose

I currently have a C++ program to read in a matrix of values (type double) and print out the transpose, how can I alter my code so that it can read in csv files rather than spaced matrix text?
I also need to write out the transposed matrix to another file after calculating it, what would be the simplest way of doing this?
int readMatrix(const string & s, vector<double> & v);
void import_csv_matrix(const char* filename_matrix, vector <double> & v, int& rows, int& columns);
int main() {
vector<double> v;
int rows = 0;
int columns = 0;
import_csv_matrix("filename.csv", v, rows, columns);
return 0;
}
int readMatrix (const string & s, vector<double> & v) {
istringstream is(s);
double n;
while (is >> n) {
v.push_back(n);
}
return v.size();
}
void import_csv_matrix(const char* filename_matrix, vector<double>& v, int& rows, int& columns) {
ifstream data_File;
string line;
data_File.open(filename_matrix);
if (data_File.is_open()) {
int i = 0;
getline(data_File, line);
columns = readMatrix(line, v);
for (i = 1; i < 100000; i++) {
if ( !getline(data_File, line) > 0) break;
readMatrix(line, v);
}
rows = i;
data_File.close();
}
cout << "Transpose:" << endl;
for (int i = 0; i < columns; i++) {
for (int j = 0; j < rows; j++) {
cout << v[i + j*columns] << "\t";
}
cout << endl;
}
}
I assume you mean that the rows are still line separated but the elements within rows are comma separated. Then all you need to do is modify the readMatrix function to handle those commas. The following code should work.
int readMatrix(const string& s, vector<double>& v) {
char comma = ',';
istringstream is{s};
for (double temp = 0.0; is >> temp; v.push_back(temp)) {
is >> comma;
if (comma != ',') break; \\ a formatting error has occurred
}
return v.size();
}

How to get input separated by space and store it in a vector in c++

I have a class having three instances, one integer - noOfCouples and two vectors - womenHotness and menHotness
I have to first take the input noOfCouples and then according to my first input i have to take input separated by spaces and create the two vectors
So far i have done this
#include <iostream>
#include <vector>
class hotness {
private:
int noOfCouples;
std::vector<int> womenHotness;
std::vector<int> menHotness;
public:
void setNoOfCouples(int num);
void setWomenHotness(std::vector<int>& hotness);
void setMenHotness(std::vector<int>& hotness);
int getNoOfCouples();
std::vector<int> getWomenHotness();
std::vector<int> getMenHotness();
};
void hotness::setNoOfCouples(int num) {
noOfCouples = num;
}
void hotness::setMenHotness(std::vector<int> &hotness) {
menHotness.swap(hotness);
}
void hotness::setWomenHotness(std::vector<int> &hotness) {
womenHotness.swap(hotness);
}
int hotness::getNoOfCouples() {
return noOfCouples;
}
std::vector<int> hotness::getMenHotness() {
return menHotness;
}
std::vector<int> hotness::getWomenHotness() {
return womenHotness;
}
int main() {
int t, i = 0, noc, k = 0, output;
std::vector<int> women(1000);
std::vector<int> men(1000);
std::cin >> t;
hotness input[1000];
while(i < t) { // this loop is just for test cases
std::cin >> noc;
input[i].setNoOfCouples(noc);
k = 0;
std::cout << "i = " << i << " k = " << k << "\n";
while(k<noc) {
std::cin >> men[k];
std::cin >> women[k];
k++;
}
input[i].setMenHotness(men);
input[i].setWomenHotness(women);
i++;
}
}
but while debugging i am getting EXC_BAD_ACCESS i.e. i guess my code is trying to access unassigned address to my vector
Is it the right way to assign take the input and assign into a new vector, or is there any mistake in my code
Please suggest most efficient way
Thanks in advance
You get the error because setMenHotness() and setWomenHotness() use the vector::swap() function.
This will swap the contents of the men vector with the menHotness vector.
So at the first iteration of the while(i < t) loop, after the call to the swap function, the menHotness vector will contain 1000 ints and the men vector will contain none.
Then, at the second iteration, you will call std::cin >> men[k];.This will try to store an integer in men[0] but men[0] does not exist anymore and so you get the error.
I would change the setMenHotness and setWomenHotness functions to use the = operator, i.e:
void hotness::setMenHotness(std::vector<int> &hotness) {
menHotness = hotness;
}
void hotness::setWomenHotness(std::vector<int> &hotness) {
womenHotness = hotness;
}
and then change the main function like this:
int main() {
int t, i = 0, noc, k = 0, output;
int user_input;
std::vector<int> women;
std::vector<int> men;
std::cin >> t;
hotness input[1000];
while(i < t) { // this loop is just for test cases
std::cin >> noc;
input[i].setNoOfCouples(noc);
k = 0;
std::cout << "i = " << i << " k = " << k << "\n";
while (k < noc) {
std::cin >> user_input;
men.push_back(user_input);
std::cin >> user_input;
women.push_back(user_input);
k++;
}
input[i].setMenHotness(men);
input[i].setWomenHotness(women);
i++;
}
}
I got the reason for EXC_BAD_ACCESS, it was because of the temporary vector men and women was not getting new instance as it was initiated before the loop for input
Update in the main
int main() {
int t, i = 0, noc, k = 0, output;
std::cin >> t;
hotness input[1000];
while(i < t) {
std::cin >> noc;
std::vector<int> women(1000);
std::vector<int> men(1000);
input[i].setNoOfCouples(noc);
k = 0;
while(k<noc) {
std::cin >> men[k];
k++;
}
k = 0;
while(k<noc) {
std::cin >> women[k];
k++;
}
input[i].setMenHotness(men);
input[i].setWomenHotness(women);
i++;
}
}

Vector of Vectors to create matrix

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