How to resize 2d vector - c++

#include <iostream>
#include <vector>
using namespace std;
int main(void)
{
vector<vector<int> > matrix;
matrix.resize(3, vector<int>(4, 1));
for (size_t i = 0; i < 3; i++)
{
for (size_t j = 0; j < 4; j++)
{
cout << matrix[i][j];
}
cout << endl;
}
matrix.resize(5, vector<int>(7, 0));
for (size_t i = 0; i < 5; i++)
{
for (size_t j = 0; j < 7; j++)
{
cout << matrix[i][j];
}
cout << endl;
}
return 0;
}
'''
As far as I know, when we are resizing a vector using "resize()" over than original capacity, values in original space will remain and new values are assigned to new space.
In the line matrix.resize(5, vector(7, 0)); If we execute that line I thought matrix would be like
1111000
1111000
1111000
0000000
0000000
something like this.
But the programs stops,
I want to know why it won't working.

matrix.resize(5, vector<int>(7, 0));
only add new vector of size 7 not modifying actual vector.
Just resize actual vectors to 7 with:
for (auto &row: matrix) row.resize(7);
so now is working:
1111000
1111000
1111000
0000000
0000000

i tested your codes using an online compiler https://onlinegdb.com/BkwcGuAAD
your columns are not resized (only the rows are resized). running your current code yields
1 1 1 1 0 0 33
1 1 1 1 0 0 33
1 1 1 1 0 0 49 << notice some columns have random numbers?
0 0 0 0 0 0 0
0 0 0 0 0 0 0
try resizing the columns too
matrix[0].resize(7,0);
matrix[1].resize(7,0);
matrix[2].resize(7,0);
matrix.resize(5, vector<int>(7, 0));
you should get something like the following
1 1 1 1 0 0 0
1 1 1 1 0 0 0
1 1 1 1 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0

By the C++ Reference
(http://www.cplusplus.com/reference/vector/vector/resize/)
void resize (size_type n);
void resize (size_type n, const value_type& val);
Resizes the container so that it contains n elements.
If n is smaller than the current container size, the content is reduced to its first n elements, removing those beyond (and destroying them).
If n is greater than the current container size, the content is expanded by inserting at the end as many elements as needed to reach a size of n. If val is specified, the new elements are initialized as copies of val, otherwise, they are value-initialized.
If n is also greater than the current container capacity, an automatic reallocation of the allocated storage space takes place.
Notice that this function changes the actual content of the container by inserting or erasing elements from it.
I thought Compiler will understand if I put more longer vector inside of "val".
That is, I thought it would understand this kind of increased "n".
But Compiler will only watch whether "n" parameter itself is changed or not.
Because of this reason, my code wouldn't work properly.
if you want to increase size of vector using size() function, note that you should resize original row values on your hand.

Related

How to generate this matrix with armadillo in c++?

I would like to generate a matrix in C ++ using armadillo that behaves like a "truth table", for example:
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
I was thinking of a cycle of this kind, but I'm not very practical with armadillo and its data structures.
imat A = zeros<imat>(8, 3);
/* fill each row */
for(int i=0; i < 8; i++)
{
A.row(i) = (i/(pow(2, i)))%2 * ones<ivec>(3).t(); //
}
cout << "A = \n" << A << endl;
Any ideas?
If you need a large size truth table matrix (~2^30 x 30) as you said here, from the memory point of view, you should implement a function which quickly calculates the values you want rather than storing them on a matrix.
This is easily done using std::bitset as follows.
Note that N must be determined at compile-time in this method.
Then you can get the value of your A(i,j) by matrix<3>(i,j):
DEMO
#include <bitset>
template <std::size_t N>
std::size_t matrix(std::size_t i, std::size_t j)
{
return std::bitset<N>(i)[N-j-1];
}

C++, vector: getting incorrect output containing 0's

Why is the vector 'r' giving the output as follows? Instead, it should not have zero in the list.
Can someone help?
output: 0 0 0 0 0 5 1 2 3 4
vector <int> leftRotation(vector <int> a, int d) {
vector<int> r(a.size());
// int j=0;
for(int i=d; i<a.size(); i++)
r.push_back(a[i]);
for(int i=0; i<d; i++)
r.push_back(a[i]);
return r;
}
You are initializing r with a.size() copies of 0 at the start of your code:
vector<int> r(a.size());
At this point, the vector r contains values 0 0 0 0 0 (as many zeroes as there are elements in a).
Then, you push values onto the back of this vector of zeroes. At each step of your loops:
0 0 0 0 0 5
0 0 0 0 0 5 1
0 0 0 0 0 5 1 2
0 0 0 0 0 5 1 2 3
0 0 0 0 0 5 1 2 3 4
Instead, initialize with an empty vector:
vector<int> r;
The local variable of vector<int> r(a.size()) uses a vector's constructor overload that accepts (size_type count) argument and is initialized (or rather zeroed out) to contain a.size() number of 0s. For clarification check out the std::vector constructor overload no. 3:
The overload (3) zeroes out elements of non-class types such as int
Use a default constructor to create an empty container instead:
std::vector<int> r;
or:
std::vector<int> r{};
vector<int> r(a.size());
With this line, you create a vector of initial size a.size(); the initial elements in the vector are set to 0.
Probably your a vector has size 5, so this is where the five zeros in your output come from:
0 0 0 0 0
Then, you invoke the push_back() method on r, and this appends other elements at the end of the r vector.
To get a better help, please clarify your goal.

c++11 using std::fill to fill a 2D dynamically allocated array

A discussion along this line could be found in this question and also in here, but my case is slightly different, as I am dealing with a dynamically allocated memory.
also please note, memset does not quite work with double value.
Anyway, I am trying to use std::fill to fill a dynamically allocated 2D array --
#include <iostream>
#include <algorithm>
using std::cout ; using std::endl ;
using std::fill ;
int main()
{
double **data ;
int row = 10, col = 10 ;
data = new double*[row] ;
for(int i = 0 ; i < col ; i++)
data[i] = new double[col];
// fill(&(data[0][0]),
// &(data[0][0]) + (row * col * sizeof(double)), 1); // approach 1
// fill(&(data[0][0]), &(data[0][0]) + (row * col), 1); // approach 2
// fill(data, data + (row * col * sizeof(double)), 1); // approach 3
// fill(&(data[0][0]),
// &(data[0][0]) +
// ((row * sizeof(double*)) +
// (col * sizeof(double))), 1); // approach 4
for(int i = 0 ; i < row ; i++) {
for(int j = 0 ; j < col ; j++)
cout << data[i][j] << " " ;
cout << endl ;
}
for(int i = 0 ; i < row ; i++)
delete [] data[i] ;
delete [] data ;
}
Approach 1: What I understand, the approach 1 should be the correct code, I am starting from the beginning &(data[0][0]) and the end of the array should be located at &(data[0][0]) + (row * col * sizeof(double)), but when I run, I get this error, but the array has been filled --
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
*** Error in `./test': free(): invalid next size (fast): 0x0000000000da3070 ***
Aborted (core dumped)
Approrach 2: However, according to this post, the approach 2 is recommended, but I do not quite understand this code, since sizeof(double) is missing, and I am getting this output --
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
*** Error in `./test': free(): invalid next size (fast): 0x0000000000bf5070 ***
Aborted (core dumped)
Approach 3: I am not sure why this does not compile, data and &(data[0][0]) should have the same meaning, right?
Approach 4: I am not sure if this is correct or not.
How do I do it ?
Does std::fill give any extra benefit over two nested loops?
Unlike a stack allocated 2D array, a dynamic 2D array is not guaranteed to be a contiguous range. It is however a contiguous range of pointers, but each pointer in the array may point to non-contiguous memory areas. In other words, the first element of data + i + 1 may not necessarily follow the last element of the array pointed by data + i. If you wonder why a stack-allocated 2D array is contiguous, it is because when you declare something like
double data[10][20];
then the compiler understands it as array of 10 (contiguous) elements, each element of type double[20]. The latter type is also an array, which guarantees contiguous elements, so the double[20] elements (i.e. 20 double one after the other) are stacked one after the other in the memory. double[10][20] is is strikingly different from double**.
That's why std::fill or std::memset gives you headaches, as they both assume a contiguous range. Therefore in your case a nested loop seems to be the simplest way of filling the array.
In general, it is much better to use a 1D array in which you "mimic" the 2D access, exactly for the reasons mentioned above: data locality. Data locality implies fewer cache missed and better overall performance.
Pointer arithmetic requires that a pointer be incremented only to the extent that the result still points at the same array (or one past the end).
You allocate each row as a separate array in your for loop:
for(int i = 0 ; i < col ; i++)
data[i] = new double[col]; // this creates a distinct array for each row
Since each row array you allocate is col elements, the maximum value that can legally be added to &(data[0][0]) is col. But in each of your examples of std::fill usage you add more to the pointer than you are allowed.
Given the way you are allocating the array, there's no way for you to pass raw pointers to a single call to std::fill in order to initialize the entire 2D array. Either you must use more than one call to std::fill (which defeats the purpose of using std::fill), or you must create an Iterator type that knows how to deal with the separate allocation of each row, or you must change the way you allocate the array.
I would recommend allocating the whole array at once as a single dimensional array and then writing some additional code to make it work like a two dimensional array. This has a number of benefits:
The standard library contains a convenient way of dynamically allocating a single dimensional arrays: std::vector
Using std::vector means you no longer need to use naked new and delete, which fixes the exception safety problem your code has.
A single allocation generally has better performance characteristics than many allocations (Of course, there are cases where separate allocations are better).
Here's a simple wrapper class to make a 1D array look like a 2D array:
class Matrix {
std::vector<double> data;
int cols;
public:
Matrix(int row, int col)
: data(row * col)
, cols(col)
{}
auto begin() { return data.begin(); }
auto end() { return data.end(); }
struct index_type { int row; int col; };
double &operator[](index_type i) {
return data[i.row * cols + i.col];
}
int row_count() const { return data.size()/cols; }
int column_count() const { return cols; }
};
Using this you can rewrite your code:
#include "Matrix.h"
#include <iostream>
#include <algorithm>
using std::cout ; using std::endl ;
using std::fill ;
int main()
{
Matrix data(10, 10);
fill(data.begin(), data.end(), 1.0);
for(int i = 0 ; i < data.row_count() ; i++) {
for(int j = 0 ; j < data.column_count() ; j++)
cout << data[{i, j}] << " " ;
cout << endl ;
}
}
Does std::fill give any extra benefit over two nested loops?
Using loops is less readable because loops could do lots of other things, and you have to spend more time figuring out what any particular loop is doing. For this reason one should always prefer using STL algorithms over manual loops, all else being equal.
// fill(&(data[0][0]),
// &(data[0][0]) + (row * col * sizeof(double)), 1); // approach 1
Pointer arithmetic automatically considers the size of the array elements. You don't need sizeof(double). Multiplying by sizeof(double) here is the same as multiplying by sizeof(double) inside []. You wouldn't do: data[i * sizeof(double)], so don't do data + (i * sizeof(double)).
Your example code uses &(data[0][0]). Think about if this the same or different from data[0]. Consider both the type and the value of the expressions.
I agree with the above comments. You have allocated 10 separate arrays so you can't initialize these with a single std::fill call.
Moreover, when you perform arithmetic operations on pointer of non-void types, a compiler automatically multiply your results by sizeof of a given type. However, when you use functions like memset or memcpy, you actually have to multiply number of elements by sizeof of a given types and pass it to one of these functions. It's because these function operate on bytes and they accept pointers of void type. Therefore it is impossible for compiler to take care of adjusting of sizes, because the void type has no specified size.

Copying data file into an array

I have a project for school. They gave me a data file that needs to be in an array of 10*10. This array needs to be an upper triangle, which means that all values of and below the diagonal have to be zero. This data file is the time that a project takes by every stage. It means that every [i][j] represents the time for stage from i to j.
Just to make it more complicated the problem ask you to find the longest time per column and add it to the longest time in the next column.
here is my code so far:
#include <iostream>
#include<iomanip>
#include <fstream>
#include <cmath>
using namespace std;
//Function prototype
int minCompletionTime (int Data[], int numTasks);
int main()
{
//Declaring and initializing variables
int num_Events(0), completion_Time(0);
int startSearch(0), endSearch(0);
const int SIZE(10);
char datch;
//Declaring an array to hold the duration of each composite activity
int rows(0),duration_Data [10];
//Declaring an input filestream and attaching it to the data file
ifstream dataFile;
dataFile.open("duration.dat");
//Reading the data file and inputting it to the array. Reads until eof
//marker is read
while (!dataFile.eof())
{
//Declaring an index variable for the array
//Reading data into elements of the array
dataFile >> duration_Data[rows];
//Incrementing the index variable
rows++;
}
//Taking input for the number of events in the project
cout << "Enter the number of events in the project >>> ";
cin >> num_Events;
//Calling the function to calculate the minimum completion time
completion_Time = minCompletionTime(duration_Data, num_Events);
//Outputting the minimum completion time
cout << "The minimum time to complete this project is " << completion_Time
<< "." << endl;
}
int minCompletionTime (int Data[], int numTasks)
{
int sum=0;
//As long as the index variable is less than the number of tasks to be
//completed, the time to complete the task stored in each cell will be
//added to a sum variable
for (int Idx=0; Idx < numTasks ; Idx++)
{
sum += Data[Idx];
}
return sum;
}
Any help will be appreciated
My data file only has 6 elements that holds this elements: 9 8 0 0 7 5
my data should look like this in order to start doing operations.
0 0 0 0 0 0 0 0 0 0
0 0 9 8 0 0 0 0 0 0
0 0 0 0 7 0 0 0 0 0
0 0 0 0 5 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
It is a little confusing. I am sorry. The first and second column should have values of zero and first row the same way. after fifth row should be all zeros as well since it will be filled with more information from other data file.
There are a few ways of solving this problem. Here are 2 very naive ways:
1. Use a 10x10 array:
Read everything in from the data file (dataFile >> data[row][col]).
Have 2 nested loops:
The outer loop iterates over columns.
The inner loop iterates over the rows of that specific column.
Since you have to find the max and the values under the diagonal is zero, you can just be lazy and find the max of each column (you might have trouble if it's a lot larger than 10x10). However, if you want to only go through the rows that are necessary, I'll let you figure it out (it's very simple, don't over think).
2. Only use a 1x10 array:
Initialize the array with the minimal value (0 or -1 should work for you), let's call it the max_row.
Read item by item on each row, and compare it to the value that's stored in the max_row and replace appropriately.
When you're done, just sum up the elements in max_row.

How to create undirected graph out of adjancency matrix?

Hello everywhere there is an explanation by drawings hot to create graph out of adj. matrix. However, i need simple pseudo code or algorithym for that .... I know how to draw it out of adj. matrix and dont know why nobody no where explains how to actually put it in code. I dont mean actual code but at least algorithm ... Many say .. 1 is if there is an edge i know that.. I have created the adj. matrix and dont know how to transfer it to graph. My vertices dont have names they are just indexes of the matrix. for example 1-9 are the "names of my matrix"
1 2 3 4 5 6 7 8 9
1 0 1 0 0 1 0 0 0 0
2 1 0 1 0 0 0 0 0 0
3 0 1 0 1 0 0 0 0 0
4 0 0 1 0 0 1 0 0 0
5 1 0 0 0 0 0 1 0 0
6 0 0 0 1 0 0 0 0 1
7 0 0 0 0 1 0 0 1 0
8 0 0 0 0 0 0 1 0 0
9 0 0 0 0 0 1 0 0 0
that was originaly a maze ... have to mark row1 col4 as start and row7 col8 end ...
Nobody ever told me how to implement graph out of matrix (without pen) :Pp
thanks
Nature of symmetry
Adjancency matrix is a representation of a graph. For undirected graph, its matrix is symmetrical. For instance, if there is an edge from vertex i to vertex j, there must also be an edge from vertex j to vertex i. That is the same edge actually.
*
*
* A'
A *
*
*
Algorithm
Noticing this nature, you can implement your algorithm as simple as:
void drawGraph(vertices[nRows][nCols])
{
for (unsigned int i = 0; i < nRows; ++i)
{
for (unsigned int j = i; j < nCols; ++j)
{
drawLine(i, j);
}
}
}
You can convert a graph from an adjacency matrix representation to a node-based representation like this:
#include <iostream>
#include <vector>
using namespace std;
const int adjmatrix[9][9] = {
{0,1,0,0,1,0,0,0,0},
{1,0,1,0,0,0,0,0,0},
{0,1,0,1,0,0,0,0,0},
{0,0,1,0,0,1,0,0,0},
{1,0,0,0,0,0,1,0,0},
{0,0,0,1,0,0,0,0,1},
{0,0,0,0,1,0,0,1,0},
{0,0,0,0,0,0,1,0,0},
{0,0,0,0,0,1,0,0,0}
};
struct Node {
vector<Node*> neighbours;
/* optional additional node information */
};
int main (int argc, char const *argv[])
{
/* initialize nodes */
vector<Node> nodes(9);
/* add pointers to neighbouring nodes */
int i,j;
for (i=0;i<9;++i) {
for (j=0;j<9;++j) {
if (adjmatrix[i][j]==0) continue;
nodes[i].neighbours.push_back(&nodes[j]);
}
}
/* print number of neighbours */
for (i=0;i<9;++i) {
cout << "Node " << i
<< " has " << nodes[i].neighbours.size() <<" outbound edges." << endl;
}
return 0;
}
Here, the graph is represented as an array of nodes with pointers to reachable neighbouring nodes. After setting up the nodes and their neighbour pointers you use this data structure to perform the graph algorithms you want, in this (trivial) example print out the number of outbound directed edges each node has.