2d vector input and display through function - c++

I have written this code to input and display a 2d vector matrix but it is not working can someone help me identify the errors.
The main function is only taking input a and b and the function are not called properly.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<vector<int>> input(int a, int b)
{
vector<vector<int>> arr;
for (int i = 0; i < arr.size(); i++)
{
for (int j = 0; j < arr[i].size(); j++)
{
cin >> arr[i][j];
}
}
return arr;
}
void display(vector<vector<int>> arr)
{
for (int i = 0; i < arr.size(); i++)
{
for (int j = 0; j < arr[i].size(); j++)
{
cout << arr[i][j] << " ";
}
}
cout << "\n";
}
int main()
{
int a, b;
cin >> a >> b;
vector<vector<int>> arr;
arr = input(a, b);
display(arr);
}

In your input function the vector arr is empty. That means arr.size() will return 0 and the loops will not happen.
If you know the dimensions of the vectors from the beginning (I assume they are the (pretty badly named) a and b variables) then you can use that to set the size:
vector<vector<int>> input(int a,int b)
{
// Create a vector of a elements, each element is in turn a vector of b elements
vector<vector<int>> arr(a, vector<int>(b));
// ...
}
See e.g. this std::vector constructor reference for more information about the constructors used (alternative 2 and 3).

Related

Rotate a 2-D array by 90 degrees

How can I take the array size input from the user and pass it to the function. I tried #define inside the function, it doesn't work since the array definition needs the array bound at compile time. I tried global variable too, it says to define a integer constant which is not feasible in my case since I want to get the size from the user. How can I solve this issue?
#include <iostream>
using namespace std;
// reverse the transposed matrix as step 2
void reverseColumns(int arr[N][N])
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N / 2; j++)
{
int temp = arr[i][j];
arr[i][j] = arr[i][N - j - 1];
arr[i][N - j - 1] = temp;
}
}
}
// take the transpose of matrix as step 1
void transposeMatrix(int arr[N][N])
{
for (int i = 0; i < N; i++)
{
for (int j = i; j < N; j++)
{
int temp = arr[i][j];
arr[i][j] = arr[j][i];
arr[j][i] = temp;
}
}
}
void rotateMatrix(int mat[N][N])
{
transposeMatrix(mat);
reverseColumns(mat);
}
// printing the final result
void displayMatrix(int mat[N][N])
{
int i, j;
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
cout << mat[i][j] << "\t";
cout << "\n";
}
cout << "\n";
}
int main()
{
int T, N;
cin >> T;
while (T > 0)
{
cin >> N;
int mat[N][N];
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
cin >> mat[i][j];
}
}
int res[N][N];
rotateMatrix(mat);
displayMatrix(mat);
}
return 0;
}
One way to make it work is get the input of rows and cols from user and make a one dimensional array dynamically.
for example:
Let ROWS and COLS be the values you got via cin.
Then the array can be declared as
int* arr = new int[ROWS * COLS];
Instead of writing arr[i][j] you have to write
arr[i * COLS + j]
Also you have to delete the array using
delete[] arr;
You are using C++ so you should take advantages of it. As kiner_shah commented the fast way to fix your code is just by use of std::vector<std::vector<int>>.
This is better solution but stil poor:
#include <iostream>
#include <vector>
using namespace std;
using Matrix = std::vector<std::vector<int>>;
Matrix makeSquereMatrix(size_t N)
{
return {N, std::vector<int>(N)};
}
// reverse the transposed matrix as step 2
void reverseColumns(Matrix& arr)
{
auto N = arr.size();
... // no changes here
}
// take the transpose of matrix as step 1
void transposeMatrix(Matrix& arr)
{
auto N = arr.size();
... // no changes here
}
void rotateMatrix(Matrix& mat)
{
transposeMatrix(mat);
reverseColumns(mat);
}
// printing the final result
void displayMatrix(const Matrix& mat)
{
for (auto& row : mat)
{
for (auto x : row)
cout << x << "\t";
cout << "\n";
}
cout << "\n";
}
void readMatrix(Matrix& m)
{
for (auto& row : m)
{
for (auto& x : row)
{
cin >> x;
}
}
}
int main()
{
int T, N;
cin >> T;
while (T > 0)
{
cin >> N;
auto mat = makeSquereMatrix(N);
readMatrix(mat);
rotateMatrix(mat);
displayMatrix(mat);
--T;
}
return 0;
}
Live demo
Better solution would be introducing a class containing std:::vector with methods performing required actions.
BTW some time ago I've made some matrix code for C. Here is live demo

How to define a multidimensional array in C++ with 'n' rows and 'm' columns and iterate values using For Loop?

I want a program that asks the number of rows and columns of the multidimensional array and then using For loop iterate values in the array.
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n, m, x;
int a[n][m];
cin>>n>>m;
for(int i; i<n ; i++)
{
for(int j; j<m ; j++)
{
cout<<"Enter the values";
cin>>x;
a[i][j] = x;
}
}
return 0;
}
here it gets error:
main.cpp|6|warning: 'm' is used uninitialized in this function [-Wuninitialized]|
main.cpp|6|warning: 'n' is used uninitialized in this function [-Wuninitialized]|
You can't declare the array unknown size. You must do it dynamically.
#include <iostream>
using namespace std;
int main()
{
int n = 0, m = 0;
//. Get the matrix's size
while (true)
{
cout << "Input the row count: "; cin >> n;
cout << "Input the column count: "; cin >> m;
if (n < 1 || m < 1)
{
cout << "Invalid values. Please retry." << endl;
continue;
}
break;
}
//. Allocate multi-dimensional array dynamically.
int ** mat = new int *[n];
for (int i = 0; i < n; i++)
{
mat[i] = new int[m];
}
//. Receive the elements.
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cout << "Input the element of (" << i + 1 << "," << j + 1 << "): ";
cin >> mat[i][j];
}
}
//. Print matrix.
cout << endl << "Your matrix:" << endl;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cout << mat[i][j] << "\t";
}
cout << std::endl;
}
//. Free memories.
for (int i = 0; i < n; i++)
{
delete[] mat[i];
}
delete[] mat;
return 0;
}
If you like to use stl, it can be simple.
#include <iostream>
#include <vector>
using namespace std;
using ROW = vector<int>;
using MATRIX = vector<ROW>;
int main()
{
int n = 0, m = 0;
MATRIX mat;
cin >> n >> m;
for (int i = 0; i < n; i++)
{
ROW row;
row.resize(m);
for (int j = 0; j < m; j++)
{
cin >> row[j];
}
mat.push_back(row);
}
for (auto & row : mat)
{
for (auto & iter : row)
{
cout << iter << "\t";
}
cout << endl;
}
return 0;
}
Some comments.
Please never use #include<bits/stdc++.h>. This is a none C++ compliant compiler extension
Please do not use using namespace std;. Always use fully qualified names.
For the above to statements you will find thousands of entries here on SO
In C++ you cannot use VLAs, Variable Length Array, like int a[n][m];. This is not part of the C++ language
You should not use C-Style arrays at all. Use std::array or, for your case std::vector.
Use meaningful variable names
Write comments
Always initialize all variables, before using them!!!
And, last but not least. You will not learn C++ on this nonesens "competition - programming" sites.
And one of many millions possible C++ solutions (advanced) could look like that:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main() {
// Read the dimension of the 3d data
if (unsigned int numberOfRows{}, numberOfCoulmns{}; (std::cin >> numberOfRows >> numberOfCoulmns) and (numberOfRows > 0u) and (numberOfCoulmns > 0u)) {
// Define a vector with the requested size
std::vector<std::vector<int>> data(numberOfRows, std::vector<int>(numberOfCoulmns, 0));
// Read all data
std::for_each(data.begin(), data.end(), [&](std::vector<int>& col) mutable
{ auto it = col.begin(); std::copy_n(std::istream_iterator<int>(std::cin), numberOfCoulmns, it++); });
// Show debug output
std::for_each(data.begin(), data.end(), [](std::vector<int>& col)
{std::copy(col.begin(), col.end(), std::ostream_iterator<int>(std::cout, "\t")); std::cout << '\n'; });
}
else std::cerr << "\nError: Invalid input given\n\n";
return 0;
}

Printing out matrix in c++, class method problem

I want to display a matrix using class and methods. Im getting "C:\Users\PC\AppData\Local\Temp\cc41EMS5.o:lab6.cpp:(.text+0x3d6): undefined reference to `Matrix::Matrix()'
collect2.exe: error: ld returned 1 exit status" error. I guess its because of printMatrix method(that worked not as a method in main), but I dont know how to fix that.
Here is the code:
#include <cmath>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
class Matrix {
public:
Matrix();
Matrix(int rowSize, int colSize);
void setSize(int rowSize, int colSize);
string printMatrix(int rowSize, int colSize);
void free_data();
void allocate_data();
private:
int rowSize;
int colSize;
double **p;
//vector<vector<int>> matrix(rowSize, vector<int>(colSize));
};
void Matrix::allocate_data() {
p = new double *[rowSize];
for (int i = 0; i < rowSize; i++) {
p[i] = new double[colSize];
}
}
void Matrix::free_data() {
for (int i = 0; i < rowSize; i++) {
delete[] p[i];
}
delete[] p;
}
void Matrix::setSize(int rowSize, int colSize) {
int newSize = 0;
p[rowSize][colSize] = newSize;
}
Matrix::Matrix(int rowSize, int colSize) {
this->rowSize = rowSize;
this->colSize = colSize;
allocate_data();
for (int i = 0; i < rowSize; i++) {
for (int j = 0; j < colSize; j++) {
p[i][j] = 0;
}
}
}
string Matrix::printMatrix(int rowSize, int colSize) {
int i, j;
int matrix[i][j];
for (int i = 0; i < rowSize; i++) //it worked in main, but doesn't in class
{
for (int j = 0; j < colSize; j++) {
0 >> matrix[i][j];
}
cout << endl;
}
cout << "Matrix" << endl;
for (int i = 0; i < rowSize; i++) {
for (int j = 0; j < colSize; j++) {
cout << matrix[i][j] << " ";
}
cout << "\n";
}
cout << endl;
}
int main() {
int rowSize;
int colSize;
cout << "Enter size of rows and columns: ";
cout << "Rows: ";
cin >> rowSize;
cout << "Cols: ";
cin >> colSize;
Matrix m;
m.printMatrix(rowSize, colSize);
return 0;
}
Please send help
You declare two constructors:
Matrix();
Matrix(int rowSize, int colSize);
But you define only one:
Matrix::Matrix(int rowSize, int colSize)
{
this->rowSize=rowSize;
this->colSize=colSize;
allocate_data();
for(int i=0; i<rowSize; i++)
{
for(int j=0; j<colSize; j++)
{
p[i][j]=0;
}
}
}
Furthermore, in `main` you call the constructor that you happened to not define:
> ```
> Matrix m;
> ```
Instead, get rid of the declaration for `Matrix::Matrix()` since you lack a definition, and use the constructor that takes two arguments:
int main()
{
int rowSize;
int colSize;
cout<<"Enter size of rows and columns: ";
cout<<"Rows: ";
cin>>rowSize;
cout<<"Cols: ";
cin>>colSize;
Matrix m(rowSize, colSize);
m.printMatrix(rowSize,colSize);
return 0;
}
## Additional improvements
You don't need to pass the size of the matrix to `Matrix::printMatrix`, since the matrix already has the size as members. By passing those parameters to `printMatrix`, you're making the class more confusing and error-prone to use. If I constructed a 3x3 matrix and tried to call `printMatrix(10,10)` on it, I would certainly invoke undefined behavior and likely crash the program.
Get rid of the parameters (in both definition and declaration) and use the existing `rowSize` and `columnSize` fields to control the loops in that function. The return type also ought to be `void`.
Also, `0 >> matrix[i][j];` makes no sense. The correct syntax is `matrix[i][j] = 0;`.
You define and use a parameterless Matrix constructor (Matrix();) but you do not implement it.
You may either:
Delete the Matrix() definition and use the constructor that you define (Matrix m(rowSize, colSize);)
Implement the parameterless constructor, creating the matrix with some predefined values. You can use a delegating constructor to call the constructor that accepts parameters
Matrix::Matrix() : Matrix(4,4) {
}
I would recommend the first option

Can someone explain me, why my code is not working?

I am completely new in C++ and I have to solve a task for college, where I have to make a struct Matrix and fill it with random integers. I marked the line with a "!" where the error appears.
It is the error C2131(Visual C++ Compiler). It says "expression did not evaluate to a constant".
struct Matrix{
int rows;
int columns;
Matrix(int r, int c){
rows = r, columns = c;
}
int produceMatrix(){
int matrix[rows][columns]; "!"
for(int i = 0; i != rows; i++){
for(int j = 0; j != columns; j++){
matrix[i][j] = rand() %10 +1;
}
}
return 0;
}
int showMatrix(){
for(int i = 0; i != rows; i++){
for(int j = 0; j != columns; j++){
cout << matrix[i][j]<< endl;
}
}
}
};
int main()
{
srand(time(0));
Matrix a(3, 4);
}
If you are planning to create your matrix with rows and columns values only known at runtime, you are better off using std::vector<std::vector<int>> to hold your data, as the static array you use needs to know its size at compile time. But if all your sizes are known at compile time and you just want flexibility of creating different matrix sizes, you can use template, for example:
#include <iostream>
#include <ctime>
template <int ROWS, int COLUMNS>
struct Matrix
{
int rows = ROWS;
int columns = COLUMNS;
int matrix[ROWS][COLUMNS] = {};
void produceMatrix()
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
matrix[i][j] = rand() % 10 + 1;
}
}
}
void showMatrix()
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
std::cout << matrix[i][j] << "\t";
}
std::cout << std::endl;
}
}
};
int main()
{
srand(time(0));
Matrix<3,4> a;
a.produceMatrix();
a.showMatrix();
}
https://ideone.com/rCLxSn
4 10 5 5
3 8 3 6
2 4 9 10
One thing is that you cannot make variable-length arrays this way.
Another thing is that if you create a variable within a function (like you were doing here with int matrix in produceMatrix()), it is then not visible in another function.
Therefore, the array containing the elements of the matrix should be declared in your struct there, where you have declared rows and columns.
To store the elements of your matrix, you can use one-dimensional array of length equal to rows*columns.
Now, you need some kind of dynamic array to be able to make it of the length not known in the compilation time.
One solution is to use a pointer and define an array with new operator in the constructor. However, if you use new, then you have to use delete at some point to deallocate memory, which here means that the destructor is needed. Another problem would be with copying of your matrices.
Another, simpler solution is to use std::vector, a container provided by c++ standard library. Here's how to do it with std::vector (you need to add #include<vector> to your file):
struct Matrix{
int rows;
int columns;
vector<int> matrix;
Matrix(int r, int c){
rows = r, columns = c;
matrix = vector<int>(c*r);
}
int produceMatrix(){
for(int i = 0; i < matrix.size(); i++){
matrix[i] = rand() %10 +1;
}
return 0;
}
int showMatrix(){
for(int i = 1; i <= matrix.size(); i++){
cout << matrix[i-1];
if(i%columns == 0) cout << endl;
else cout << " ";
}
return 0;
}
};
As many people commented, please go through a good C++ book to learn about arrays, classes, structs etc. As for your code, the following might produce what I think you want:
#include <iostream>
#include <vector>
struct Matrix
{
int rows;
int columns;
std::vector<std::vector<int>> matrix;
Matrix(int r, int c): rows(r), columns(c)
{
matrix.resize(r);
for(int i = 0; i < r; i++)
matrix[i].resize(c);
}
int produceMatrix()
{
for(int i = 0; i != rows; i++)
for(int j = 0; j != columns; j++)
matrix[i][j] = rand() %10 +1;
return 0;
}
int showMatrix()
{
for(int i = 0; i != rows; i++)
{
for(int j = 0; j != columns; j++)
std::cout << matrix[i][j]<<" ";
}
std::cout<<'\n';
}
};
int main()
{
srand(time(0));
Matrix a(3, 4);
a.produceMatrix();
a.showMatrix();
}

C++ 2D Array - Error invalid types ‘int[int]’ for array subscript

I am trying to create MxN matrix using 2D-arrays in C++.
The createMatrix() function asks for user input for matrix items and the printMatrix() function has to print the matrix.
But the printing task is not working (I can't access the array created, I don't understand why)
I receive the error :
matrix.cpp:35:20: error: invalid types ‘int[int]’ for array subscript
cout << matrix[i][j];
The code I'm working with is:
#include "iostream"
using namespace std;
// user input matrix
int createMatrix(int m, int n){
int arr[m][n];
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cout << "A[" << i << "][" << j << "] : ";
cin >> arr[i][j];
}
cout << endl;
}
return arr[m][n];
}
/*
void printMatrix(int matrix[][2], int m, int n){
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cout << matrix[i][j];
}
}
}
*/
int main(){
int m = 2, n = 2; // m = rows, n = columns
int matrix = createMatrix(m,n);
// printMatrix(matrix, m, n); // not working as sub-routine too, main target to make it work with sub-routine
// to print matrix
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cout << matrix[i][j];
}
}
return 0;
}
matrix is an int not an int[][]. Since it is an int there is no subscript operator and that is why you are getting the error you are getting. You are also using veriable length arrays which is not standard C++. I would suggest you change your code to use a std::vector like
std::vector<std::vector<int>> createMatrix(int m, int n)
{
std::vector<std::vector<int>> arr(m, std::vector<int>(n));
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cout << "A[" << i << "][" << j << "] : ";
cin >> arr[i][j];
}
cout << endl;
}
return arr;
}
And then main() would be:
int main(){
int m = 2, n = 2; // m = rows, n = columns
std::vector<std::vector<int>> matrix = createMatrix(m,n);
// printMatrix(matrix, m, n); // not working as sub-routine too, main target to make it work with sub-routine
// to print matrix
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cout << matrix[i][j];
}
}
return 0;
}
Your matrix is not array. it is int.
You need to work with the pointers.
Yes, createMatrix works but you won't be able to do anything with what it created. Because:
arr[n][m] is local (and out of boundaries by the way). It is not a matrix as you probably thought but an item of arr at position [n][m].
It is not well defined to declare array of fixed sizes with vary sizes that depend on function input.
You need to pass to createMatrix array from the main() as pointer (like you did in printMatrix) and createMatrix should work with it and not something local.
Now regarding your original question:
But the printing task is not working (I can't access the array
created, I don't understand why)
matrix was defined as int, not as array.
int matrix = createMatrix(m,n);