How to add items to a 2-dimensional dynamic vector - c++

I have so far been able to use 1-d vectors, adding or removing elements with push/pop back.
However, when trying to fill out a 2-d vector which is supposed to represent a matrix, I run into problems. I haven't been able to use these functionalities with my 2-d vector. When the code does compile and run I get the bits asking for dimension and then it asks for the first element [1,1], for any value entered I get "Segmentation fault: core dumped". I have no idea what is going on and have been trying to modify bits of my code but to no great success, the internet has also been rather useless in giving an easy guide on how to fill out these damn things...
Thank you so much!
Here is my code
#include <iostream>
#include <vector>
using namespace std;
vector<vector<double> > readMatrix();
int main()
{
vector<vector<double> > matrix1 = readMatrix();
vector<vector<double> > matrix2 = readMatrix();
}
vector<vector<double> > readMatrix()
{
cout << "Entering a matrix" << endl;
cout << "Number of Lines : ";
int numberOfLines;
cin >> numberOfLines;
cout << "Number of Columns :";
int numberOfColumns;
cin >> numberOfColumns;
vector<vector<double> > matrix;
int i(0);
int j(0);
while(i<=numberOfLines && j<=numberOfColumns)
{
cout << "[" << i+1 << "," << j+1 << "] =" ;
int value;
cin >> value;
matrix[i].push_back(value);
cout << endl ;
j++;
if(j==numberOfColumns)
{
j=1;
i++;
}
}
return matrix;
}

Declare the matrix like this:
vector<vector<double> > matrix (y, vector<double> (x, 0));
Now you have an y*x matrix. If you want to use push_back you have to declare the x-vector when starting on a new row.

When you do vector<vector<double> > matrix; you initialize a vector of vectors, both of size 0 (that's the default), so when you do matrix[i].push_back(value) even when i==0 you access memory which you hasn't been allocated. it's better if you do pre-allocate memory like this:
vector<vector<double> > matrix(numberOfLines,vector<double>(numberOfColumns));
And then you don't need to push back or anything, you just do matrix[i][j]=whatever.

In C++ you can use the vector constructor to automatically define the size:
vector<vector<double> > matrix(numberOfLines, vector<double>(numberOfColumns, 0));
With vectors, for loops are better than while loops because the size is always known. I suggest you iterate over the vector rows and columns with these (and remove your push_back statements.)

you need to do something like:
matrix.resize( ... );
.
.
.
matrix[i].push_back( ... );
The problem here is that you don't have a two dimensional vector. You have a vector, of vectors, of doubles. You need to put some vectors in the first vector, calling resize() as above is one way. You could also pass an initial size to the constructor, you could push the vectors on one by one - though that could carry performance issues.

Related

Unable to create a Two Dimensional Array with random parameters

So I am a Beginner in C and I was going through Arrays and i was having success with arrays restricted to bounds of constant integers...
But i also wanted to find out what happens if we give in a random number for the Numbers of Rows and columns..
However when i executed the program all was fine until the 4th element wherein Vscode with display an error message of Matrix.exe(The compiled file) not working..
I somehow guessed that the error was with vscode itself..(i might be horribly wrong)
So i went for an online compiler and didnt get the desired result..which was received easily with bounded constant integers..
The code is about treating a two dimensional array as a Matrix and then getting the desired result in a table form i.e to get a print of all the elements in a tabular form.
I will post the code now:
`
#include<iostream>
using namespace std;
int main()
{
int m,n;
int matrix[m][n];
cout<<"Please give the number of Rows:";
cin>>m;
cout<<"Please give the number of columns:";
cin>>n;
for (int i=0;i<m;++i)
{
for (int j=0;j<n;++j)
{
cout<<"Please enter matrix element:";
cin>>matrix[i][j];
}
}
//printingmatrix
cout<<"The Matrix is:";
for (int a=0;a<m;a++)
{
for (int b=0;b<n;b++)
{
cout<<matrix[a][b]<< " ";
}
cout<<endl;
}
}`
I dont actually know what the problem is the code might be incorrect but seemed logically correct to me...
I actually dont have any idea of why i am not receiving the result!
Also this is my first stack ques so sorry if I sucked at asking! ;)
Any help will be appreciated!
Thanks!
int m,n;
int matrix[m][n];
There are two big problems here.
Problem 1: You don't give any value to m nor n. Then you use these ungiven values as the size of an array. C++ is not a "dataflow" language. If you use a value, the program won't stop, and wait for you to initialise the value later. If you use an uninitialised value, then the behaviour of the program will be undefined. There are exceptions, but none that apply to this case, so the behaviour of your program is undefined. That is something to avoid. Solution: Don't ever use uninitialised values.
Problem 2: The values that you later give are not compile time constant. The size of an array variable must be compile time constant in C++. The program is ill-formed. Solution: If you need an array with runtime size, then you must allocate it dynamically. The simplest solution is to use std::vector provided by the standard library.
So I am a Beginner in C
Note that C and C++ are two distinct languages.
In addition to #eerorika's answer, if you want to have a modern solution to your problem you can use std::vector<std::vector<int>> to have a dynamic 2d array.
A std::vector can be resized by simply calling .resize(n).
A std::vector stores the length, get it by calling .size()
An element inside a vector can be accessed via []
With this information, you can rewrite your code to look like this:
#include <iostream>
#include <vector>
int main() {
int m, n;
std::cout << "Please give the number of Rows: ";
std::cin >> m;
std::cout << "Please give the number of columns: ";
std::cin >> n;
std::vector<std::vector<int>> matrix;
matrix.resize(m);
for (int i = 0; i < matrix.size(); ++i) {
matrix[i].resize(n);
}
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
std::cout << "Please enter matrix element [" << i << ", " << j << "] : ";
std::cin >> matrix[i][j];
}
}
std::cout << "The Matrix is:\n";
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
std::cout << matrix[i][j] << " \t";
}
std::cout << '\n';
}
}
Example run:
Please give the number of Rows: 3
Please give the number of columns: 2
Please enter matrix element [0, 0] : 0
Please enter matrix element [0, 1] : 5
Please enter matrix element [1, 0] : -3
Please enter matrix element [1, 1] : 11
Please enter matrix element [2, 0] : 20
Please enter matrix element [2, 1] : 99
The Matrix is:
0 5
-3 11
20 99
You can read here why using namespace std; is considered bad practice.
Read about range-based for loop to learn more on how to use std::vector in a modern approach.
The problem with your original code is that C++ does not allow you to declare or initialize arrays with non-constant values for dimensions.
You can easily fix this issue if you use C++ STL vector as shown in the code below:
First, please note that you will need to include the header vector
Second, please see how I instantiate the vector matrix as a 2D array in the code. And, I also removed one line of your old code, and instead added the declaration for the vector matrix.
#include<iostream>
#include<vector> // This line must be added to use STL vector
using namespace std;
int main()
{
int m,n;
//int matrix[m][n]; // I removed this line
cout<<"Please give the number of Rows:";
cin>>m;
cout<<"Please give the number of columns:";
cin>>n;
vector<vector<int>> matrix(m, vector<int>(n, 0) ); // I added this line
for (int i=0;i<m;++i)
{
for (int j=0;j<n;++j)
{
cout<<"Please enter matrix element:";
cin>>matrix[i][j];
}
}
//printingmatrix
cout<<"The Matrix is:";
for (int a=0;a<m;a++)
{
for (int b=0;b<n; b++)
{
cout<<matrix[a][b]<< " ";
}
cout<<endl;
}
}
Note: I have tested and verified the code above run well. Please let me know if you have any issue.

how to divide an array into different arrays in c++

I have written this code in c++ to read a signal as an array and now I need to segment this array for 4 or 5 different arrays such that put first 20 elements in array1 ;20-50 in array2 and so on ..
how to do that in c++
my code :
int main()
{
// first we use for loop to insert the signal as arry by the user......
int size;
cout << "this programme read your signal as array first you need to "
"determine the size of the array "
<< endl
<< " Enter desired size of the array";
cin >> size;
vector<float> sig(size);
cout << "the signal " << endl;
for (int x = 0; x < size; x++)
{
cin >> sig[x];
}
}
To create a vector with a subrange of another vector you can use the constructor that takes two iterators( (5) in the link):
std::vector<float> x(100);
std::vector<flaot> y(x.begin()+begin,x.begin()+end);
y will have copies of elements from index begin till end (end not included) from x.
However, I would rather store the elements in the right place from the start instead of reading them into a vector<float> sig(size); first. Alternatively you can consider to keep all input in a single vector and pass iterators to functions that need to work with subranges of the full signal instead of splitting the signal.

User in a variable?

I am a beginner and I would like to ask you something.
We have an array whose size depends on value input by user in a variable ‘arraysize’. Look at below code and comments please, is it a correct way to achieve this said be behaviour?
int * myArray = NULL;
int arraySize;
cout << "Enter array size: ";
cin >> arraySize;
myArray = new int[arraySize];
delete [] myArray;
The earlier answer was a community wiki. Since you asked for an example, here's a more detailed answer.
A std::vector is a class belonging to the standard template library read in detail.
//since you used "using namespace std;" I'm omitting the "std::"
Declaration
vector< int > v; //creates a vector of integers
vector< double > vd; //vector of double values
This is quite similar to int a[/*any number*/].
Inserting values
v.push_back(5); //adds 5 to the end of the vector (or array of variable size)
With the above two lines you dont need to know in advance how many numbers you'll have to store.
One more sample code.
#include <iostream>
#include <vector>
int main ()
{
std::vector<int> myvector;
int myint;
std::cout << "Please enter some integers (enter 0 to end):\n";
do {
std::cin >> myint;
myvector.push_back (myint);
} while (myint);
std::cout << "myvector stores " << int(myvector.size()) << " numbers.\n";
return 0;
}
This program reads values and saves to myvector till 0 is entered in input.
Iteration
std::vector<int>::size_type sz = myvector.size(); //even int works here
// assign some values:
for (unsigned int i=0; i<sz; i++) myvector[i]=i;
Deletion
v.pop_back(); //removes last element
Use std::vector as a C++ best practice.

How to pushback a vector of 3 elements into a vector in C++?

I have a long vector of values, a specified user input of row/column size. I need to assign a set of 3 numbers into a vector, from the long list of vectors. The vector with 3 number set will be pushed back into another vector, with user input row/column size. 1 column = the 3 number vector set and so on, until every column is filled out. I have trouble making this code (it needs to be in a loop). Any help please?
The picture is an example of a 4x4 vector, with each column a vector of 3 numbers
It sounds as if you want nested vectors, where each smaller vector inside your "long vector" represents a column of 3 values. If so you could do so like:
std::vector<int> columnVec = { 1, 2, 3 };
std::vector<std::vector<int>> longVector;
longVector.push_back(columnVec);
In the first line we declare a vector representing our column and place three integers inside it. On line two we declare another vector, but this time containing vectors which themselves contain ints, i.e. a vector full of column vectors. We then used push_back() to push the column vector into our vector of vectors. If you needed to print the values you could do so like:
for(auto& vec : longVector) { //Walk through our vector of vectors.
for(int value : vec) { //Walk through our column vectors of values.
std::cout << value; //Print out each value of the column.
}
std::cout << std::endl; //Add a newline.
}
Note that if you print them, the columns will appear as rows in the console. If you care about the formatting in the console it will take a bit more effort and might be worth asking as a separate question.
One possible approach might look something like this:
#include <iostream>
#include <cstdlib>
#include <vector>
using namespace std;
int main()
{
typedef std::vector<int> VecInt;
typedef VecInt::iterator VecIntIter;
typedef std::vector<VecInt> VecVecInt;
typedef VecVecInt::iterator VecVecIntIter;
VecVecInt rows;
const int maxRows = 10, maxCols = 10;
cout << "Values during creation" << endl;
cout << "----------------------" << endl;
for (int rowNum=0; rowNum<maxRows; rowNum++)
{
VecInt curRow;
for (int colNum=0; colNum<maxCols; colNum++)
{
if (colNum != 0)
cout << " ";
int cellValue = rand() % 32;
cout << cellValue;
curRow.push_back( cellValue );
}
cout << endl;
rows.push_back(curRow);
}
cout << endl;
cout << "Values during retrieval" << endl;
cout << "----------------------" << endl;
for (VecVecIntIter rowIter=rows.begin(); rowIter!=rows.end(); rowIter++)
{
VecInt curRow = (*rowIter);
for (VecIntIter colIter=curRow.begin(); colIter!=curRow.end(); colIter++)
{
if (colIter != curRow.begin())
cout << " ";
cout << (*colIter);
}
cout << endl;
}
}
Though, this will store a collection of rows, rather than a collection of columns. Easy enough to change the for loops.

Expanding vectors inside a vector

I'm using a matrix of characters by defining a vector of vectors of chars the following way.
std::vector<std::vector <char> > CharMap;
std::vector <char> temp(sizeY, '.');
std::vector <std::vector <char> > temp2(sizeX, temp);
CharMap = temp2;
This has been working fine so far, but now I need to expand the innermost vectors during runtime and something is going wrong.
cout << (int) CharMap[0].size();
CharMap[0].push_back( '.' );
cout << (int) CharMap[0].size();
CharMap[0] is a vector of chars. This code compiles with no problem. When it runs, the size of the vector simply doesn't change. All I'm trying to do here is increase the size by 1, but the ouput is the same on both couts. Why isn't the size increasing?
Inside the actual code I will increase the size of all CharMap[i], iterating overi. But right now even this simplified version isn't working.
A quick test program seems to work as expected:
#include <vector>
#include <iostream>
int main() {
std::vector<char> temp(17, '.');
std::vector<std::vector<char> > map(10, temp);
for (int i=0; i<map.size(); i++) {
std::cout << "Before addition, size = " << map[i].size();
map[i].push_back('.');
std::cout << ", after addition, size = " << map[i].size() << "\n";
}
return 0;
}
I suppose you could try that and see what it produces with your compiler -- it's barely possible it won't, in which case you've apparently discovered a bug. If it does work, then the problem is apparently in some code you haven't shown us.