Say if I have a 2d vector of Int:
vector <vector<Int> > myV;
Then I define 2 variables:
int rows; //number of vectors in myV. This is the my y(vertical) index.
int columns; //number of elements in one vector within myV. x index.
I want to know when I output myV like a rectangle: iterate through myV[something][something], which variable should be in the left bracket, and which should be right? I just want the variables to fit perfectly into my intention.
I also wrote a test code, but it has segmentation fault that I haven't figured out why.
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<vector<int> > myV;
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++){
myV[i][j] = j;
}
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++)
cout << myV[i][j] << " ";
cout << endl;}
}
The reason your code is not working is because you haven't allocated any memory for your vector. Change the declaration of the vector to:
vector<vector<int>> myV(3, vector<int>(3));
On a side note, I would even consider storing your array in one dimension (i.e std::vector<int> myV(9);) and compute indexes for multidimensional use using a function getIndex, which could be implemented as:
inline std::vector<int>::size_type getIndex(int numCols, int i, int j)
{
return i * numCols + j;
}
Usage of this function may look like:
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++i)
{
myV[getIndex(3, i, j)] = /* Value */;
}
}
This would avoid the large use of memory a multidimensional vector needs, and would allow usage in pretty much the same way.
Here is some further reading for more information on why one should use 1d arrays for representing 2d arrays.
Related
say I have a 3x4 array with integer elements, I want to pass this array to a function that then takes all of the elements and multiplies them by some integer 'b' then returns this new array, how would I go about it? this is what I have currently
#include <iostream>
#include <math.h>
using namespace std;
// my function for multiplying arrays by some integer b
int* multarray(int (*a)[4], int b)
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
*(*(a+i)+j) *= b;
}
}
return *a;
}
int main()
{
// creating an array to test, values go from 1-12
int arr [3][4];
int k = 1;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
arr[i][j] = k;
k++;
}
}
// trying to setup new 'array' as a product of the test array
int *newarray;
newarray = multarray(arr,3);
// printing values (works with *(newarray+i) only)
for (int i = 0; i < 3; i++)
{
for (int j=0; j<4; j++)
{
cout << *(*(newarray+i)+j);
}
}
return 0;
}
this works if I don't include the j part when printing all my values but as it is now, tells me I have an error: invalid type argument of unary '*' (have 'int')
Your function is not returning a new array, it's modifying an existing array. So (assuming this is not a problem for you) you should just change the return type to void.
void multarray(int (*a)[4], int b)
{
...
}
Then
multarray(arr,3);
for (int i = 0; i < 3; i++)
{
for (int j=0; j<4; j++)
{
cout << *(*(arr+i)+j);
}
}
If you really do want a function that returns a new array, then that's a whole different (and much more complicated) problem . Apart from anything else it's, strictly speaking, impossible to return an array in C++.
I cannot seem to find the reason why the contents of my vector components are not supplied using the for loop and cout. Background to the code is that I want to know what happens when you resize a vector that already exists (if made smaller, which components fall away, if larger, which components are added,...)
#include <iostream>
#include <vector>
#include <iomanip>
#include <cmath>
using namespace std;
int main()
{
vector<double> a;
for (int i = 1; i < 10; ++i)
a[i] = 5;
a.resize(15)
for (int i = 1; i < a.size(); ++i)
cout << a[i] << endl;
return 0;
}
The program has undefined behavior because the declared vector is empty and you may not use the subscript operator for an empty vector.
vector<double> a;
for (int i = 1; i < 10; ++i)
a[i] = 5;
Moreover the indices of vectors start from 0.
You could either write
vector<double> a( 10 );
for (int i = 0; i < 10; ++i)
a[i] = 5;
or
vector<double> a;
for ( int i = 0; i < 10; ++i)
a.push_back( 5 );
Or to make the last code snippet more efficien you could write
vector<double> a;
a.reserve( 10 );
for ( int i = 0; i < 10; ++i)
a.push_back( 5 );
Again to output the full content of the vector you should start indices from 0. Or you could use the range based for loop like
for ( const auto &item : a ) std::cout << item << '\';
You have an out-of-bounds access in your code. You need to resize your vector before filling it. Alternatively you can use push_back to insert elements.
In either case, it will work as you expect.
You did not change the size of the vector. To insert into a vector you can use the push_back or emplace_back methods. If you change the insertig code to
for (int i = 1; i < 10; ++i)
a.push_back(i);
or alternatively use the resize method before you assign
a.resize(10);
for (int i = 1; i < a.size(); ++i)
a[i] = i;
then the print loop should work fine.
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();
}
I'm trying to change a 2D array values in different function so it suits my need.
For an example in the code below I'm trying to change the Matrix to reflexive by changing the to "1" .
I have an issue returning the new array and replace it with the old one in the main program so I can use it again.
int reflexive(int m, int n, int matrix[100][100])
{
for(int i = 1;i <= m; i++)
{
for(int j = 1; j <= n; j++)
{
if(i == j)
{
if(matrix[i][j] != 1)
matrix[i][j] = 1;
}
return matrix;
}
}
}
int main()
{
int matrix[100][100];
int m , n;
for(int i = 1;i <= m; i++)
{
for(int j = 1; j <= n; j++)
{
cin>>matrix[i][j];
}
}
matrix[m][n] = reflexive(m,n,matrix);
return 0;
}
I want to fix this code so it can return the full new 2D array to the main program.
In your function reflexive the return statement is inside the loop. This causes that the function is terminated immediately when the return statement is reached. If you would proper format your code you would be able to see this behavior easily.
Further note, that the first element in an array has the index 0 and the index of the last element is the the size of the array -1. This is, because the array index is the element "offset". This means that
a[i]
and
*(a + i)
access the same array element.
for(int i = 1;i <= m; i++) // <--- should be for(int i=0; i<m; i++)
{
for(int j = 1; j <= n; j++) // <--- should be for(int j=0; j<n; j++)
{
if(i == j)
{
if(matrix[i][j] != 1)
matrix[i][j] = 1;
}
return matrix; // <--- here the function is terminated
}
}
An array is passed to a function by a pointer and not by value. This means if a formal parameter of a function is an array, then not all the values of the actual parameter are copied to the array. There is only passed a pointer to the values of the paramter to the function.
Because of that you do not need any return value in your case.
The following code should do what you want:
int reflexive(int m, int n, int matrix[100][100])
{
for(int i=0; i<m; i++)
{
for(int j=0; j<n; j++)
{
if(i == j)
{
if(matrix[i][j] != 1)
matrix[i][j] = 1; // <----- write to the data by pointer
}
}
}
}
int main()
{
int matrix[100][100];
......
reflexive(m,n,matrix);
......
}
Use vector<vector<int>> and pass it by reference
Using an array here is tedious and error-prone. Therefore:
#include <vector>
std::vector<std::vector<int> > reflexive(std::vector<std::vector<int> > matrix)
{
for(int i = 0; i < matrix.size; i++){
for(int j = 0; j < matrix[i].size; j++){
....
int main()
{
std::vector<std::vector<int> > matrix(100, std::vector<int>(100));
int m , n; //<<whereever they come from I guess? Saw no cin in your code. Have no set value right now.
for(int i = 0; i < m; i++)
{
for(int j =0; j < n; j++)
{
cin>>matrix[i][j];
}
}
}
or
#include<array>
...
std::array<std::array<int, 100>, 100> matrix;
std::array is of fixed size, std::vector is dynamic. Also learn about std::list while you're at it.
In any case, you should find a basic tutorial that talks about them and read all of it. Important standards.
That said, especially if you want to use dynamic sized arrays, you have no guarantee that every sub-array is of the same size ("a jagged 2d array), which is somehwat okay in a small program but should be avoided in the big picture, by using a class that ensures this property.
In the case of a matrix, one easy option is to use a library that deals with matrices, like for example Eigen.
edit:
If at some point you need the code above in const-correct:
std::vector<std::vector<int> > reflexive(const std::vector<std::vector<int> >& input)
{
std::vector<std::vector<int> > output = input;
....
return output;
}
(or make it void if it is allowed to modify the original matrix)
I am trying to add values to a 2D vector by using both indices. When I run my program, I get the windows message saying the program has stopped working. Using Dev-C++ to debug showed that there was a segmentation fault (I am not sure what this means). Please do not suggest using arrays, I have to use vectors for this assignment.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char** argv) {
vector< vector<int> > matrix;
cout << "Filling matrix with test numbers.";
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
matrix[i][j] = 5; // causes program to stop working
}
}
}
I have created a test case where I want to fill a 3X3 matrix with the value 5. I suspect that it has something to do with the size of the 2D vector not being specifically defined. How would I fill a 2D vector with values by using the indices?
As written, this is problematic, you are trying to write to a vector for which you did not yet allocate memory.
Option 1 - Resize your vectors ahead of time
vector< vector<int> > matrix;
cout << "Filling matrix with test numbers.";
matrix.resize(4); // resize top level vector
for (int i = 0; i < 4; i++)
{
matrix[i].resize(4); // resize each of the contained vectors
for (int j = 0; j < 4; j++)
{
matrix[i][j] = 5;
}
}
Option 2 - Size your vector when you declare it
vector<vector<int>> matrix(4, vector<int>(4));
Option 3 - Use push_back to resize the vector as needed.
vector< vector<int> > matrix;
cout << "Filling matrix with test numbers.";
for (int i = 0; i < 4; i++)
{
vector<int> temp;
for (int j = 0; j < 4; j++)
{
temp.push_back(5);
}
matrix.push_back(temp);
}
You have not allocated any space for your 2d vector. So in your current code, you are trying to access some memory that does not belong to your program's memory space. This will result in Segmentation Fault.
try:
vector<vector<int> > matrix(4, vector<int>(4));
If you want to give all elements the same value, you can try:
vector<vector<int> > matrix(4, vector<int>(4,5)); // all values are now 5
vector<int> v2d1(3, 7);
vector<vector<int> > v2d2(4, v2d1);
for (int i = 0; i < v2d2.size(); i++) {
for(int j=0; j <v2d2[i].size(); j++) {
cout<<v2d2[i][j]<<" ";
}
cout << endl;
}