Dynamically create matrix from numerical input in C++

冷暖自知 提交于 2021-02-09 09:34:09

问题


I have a console application where I am trying to create a binary matrix from a numerical input.

If a want to create a 2x4 matrix I must do two inputs inputs, one for each row. The input (console) will then look like this:

First input:

1101

second input:

0111

And then I want to create a matrix that will look like this:

{
 1,1,0,1
 0,1,1,1
}

When the user is typing 1101 in the console, the number should be splitted into its digits and each digit will be stored in different indexes in the columns. It is assumed that the user will only put in numbers of 1's and 0's. I will add a test for that later.

All my attempts of this is creating the matrix in wrong formats and therefore when I try to read the data in the matrix I get wrong results.

This is my attempt so far:

Constructor that asks the user what size the matrix will be

Matrix::Matrix() {
    std::cout << "Enter size of matrix:" << std::endl;
    std::cout << "Rows: ";
    std::cin >> rows;
    std::cout << "Columns: ";
    std::cin >> cols;

    int EndX = rows;
    int EndY = cols;
    vect3 = CreateMatrix(rows); //This method is supposed to create the matrix
}

The CreateMatrix method:

std::vector<std::vector<int>> Matrix::CreateMatrix(int row) {
    std::string number{};
    for (size_t i = 0; i < row; i++) {
        std::cout << "Enter row number " << i << ":" << std::endl;
        std::cin >> number;
        for (size_t i = 0; i < number.length(); i++)
            vect2.push_back(number[i] - '0');
        std::reverse(vect2.begin(), vect2.end());
        vect.emplace_back(std::move(vect2));
    }
    return vect;
}

The CreateMatrix function is not creating the desired matrix that I want to create but i can't figure out what I am doing wrong.

When I do this test later in the code

if (vect[row][col]) {
    // Some code
}

The numbers are in the wrong place in the matrix so I this test i evaluating to true when it is expected to be false and vice versa.

If I were to create the array manually on the stack with the example from abow it will look like this:

int matrix[2][4]{
             {1,1,0,1},
             {0,1,1,1}
         };

And if I do this test now:

if (matrix[row][col]) {
    // Some code
}

The expression is evaluating to true and false as expected.

so When I try to create the matrix dynamically by custom input the matrix does not have the correct format i.e. the numbers are in the wrong indexes.

The problem is in the std::vector<std::vector<int>> Matrix::CreateMatrix(int row) method but I can't fiure out what I am doing wrong so any help will be appreciated.

Thanks!

Matrix.h:

class Matrix {
public:
    Matrix();
    std::vector<std::vector<int>> CreateMatrix(int);
    std::vector<std::vector<int>> getMatrix()const;; //Returns vect3
    ~Matrix();

private:
    std::vector<std::vector<int>> vect{0};
    std::vector<int> vect2{0};
    std::vector<std::vector<int>> vect3{0};
};

Edit:

getMatrix:

std::vector<std::vector<int>> Matrix::getMatrix() const { return vect3; }

Testing:

Matrix matrixClass;
    std::vector<std::vector<int>> matrix = matrixClass.getMatrix(); //Returns vect3 from the Matrix class

    if (matrix[1][0]) //Should print false but prints true
        std::cout << "true\n";
    else
        std::cout << "false\n";

    int matrixxx[2][4]{
        {1,1,0,1},
        {0,1,1,1}
    };

    if (matrixxx[1][0]) //prints false
        std::cout << "true\n";
    else
        std::cout << "false\n";

    std::cin.get();
    std::cin.get();
    return 0;

Given the same matrix described abow:

    {
     1,1,0,1
     0,1,1,1
    }

The name matrix is the matrix that I try to create by user input. When I test the number at index [1][0] the program should print false because the number at that index is a 0. But the program is printing true which means in some way there is a 1 at this index even though it should not be.

The second attempt I create a matrix manually on the stack, I call it matrixxxand when I now try to acces this matrix number at index [1][0] the program do print false just as expected.


回答1:


I did not have the patience to read your code. I hope I understood your problem.

  • Try to keep user interface separated from data: don’t ask for user input in constructor.

  • Use only one vector to store your data:

    class matrix_t
    {
      size_t col_count, row_count;
      vector< bool > data;
      //...
    
  • Write a function to compute the index in vector, starting from column and row index. This way you may look at the vector as it would be a matrix:

    size_t as_index( const size_t col, const size_t row ) const;
    
  • Write a subscript function. The function will use the above index conversion function:

    auto at( const size_t col, const size_t row );
    

    You may also add a subscript function for constant objects.

  • Write a read & a write function. You must read the input character, by character:

    istream& read( istream& is );
    ostream& write( ostream& os );
    

    You may also add extraction & insertion operators.

  • Usage:

    size_t col, row;
    cin >> col >> row;
    
    matrix_t m( col, row );
    m.read( cin );
    

Full code (demo):

#include <iostream>
#include <vector>

using namespace std;

class matrix_t
{
  size_t col_count, row_count;
  vector< bool > data;

  size_t as_index( const size_t col, const size_t row ) const
  {
    return row * col_count + col;
  }

public:

  matrix_t( const size_t col_count, const size_t row_count )
    : col_count( col_count )
    , row_count( row_count )
    , data( row_count*col_count )
  {
    // nop
  }

  auto at( const size_t col, const size_t row ) const
  {
    return data[ as_index( col, row ) ];
  }

  auto at( const size_t col, const size_t row )
  {
    return data[ as_index( col, row ) ];
  }

  istream& read( istream& is )
  {
    for( size_t r = 0; r < row_count; ++r )
    {
      for( size_t c = 0; c < col_count; ++c )
      {
        char t;
        is >> t;
        at( c, r ) = t == '0' ? false : true;
      }
    }
    return is;
  }

  ostream& write( ostream& os )
  {
    for( size_t r = 0; r < row_count; ++r )
    {
      for( size_t c = 0; c < col_count; ++c )
      {
        os << at( c, r ) ? '1' : '0';
      }
      os << endl;
    }
    return os;
  }

};

int main()
{
  size_t col, row;
  cin >> col >> row;

  matrix_t m( col, row );
  m.read( cin );

  cout << endl;
  m.write( cout );

  return 0;
}


来源:https://stackoverflow.com/questions/53045856/dynamically-create-matrix-from-numerical-input-in-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!