Vector of Vectors to create matrix

2020-01-23 16:00发布

问题:

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?

回答1:

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.



回答2:

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.



回答3:

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


回答4:

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



回答5:

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 
}


回答6:

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


回答7:

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 :)



回答8:

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

'''