Accessing values from a two dimensional initialized array - c++

int a[][30]={{2, 16},{4, 8},{5, 16, 21},{2,6,3,5,6}};
Since the size of the second dimension is varying. If I want to access something like for a particular value of i(first dimension), access all j values(2nd dimension), how do I write that statement?
What I thought was:
for(int j=0;j<30;j++)
a[i][j]=some operation;
but its unnecessarily looping till 30 which is the max value. What's the efficient way to do it?
Thanks.

The compiler does not keep any information about how many values were in the braced initializer. Instead, it fills the "missing" values with zeros.
So these two are equivalent:
int a[][4] = {{2, 16},{4, 8, 5}};
int a[][4] = {{2, 16, 0, 0}, {4, 8, 5, 0}};
If you know that none of the "actual" data elements are zero, you can stop your loop when you find a zero element. Otherwise, you'll need to set up the data differently.

The size of both dimensions is fixed. The outer dimension has size 4 and the inner has size 30.
If you iterate over the inner dimension, then you will print lots of zeros, as that is what you initialize the remaining integers that aren't explicitly initialized to.
You seem to want this:
std::vector<int> a[] = {
boost::list_of(2)(16),
boost::list_of(4)(8),
boost::list_of(5)(16)(21),
boost::list_of(2)(6)(3)(5)(6)
};

Related

which is best way to initialize array, "memset" or " {//value} "?

int main(){
int ar[50]={1};
//OR
int br[50];
memset(br, 1, sizeof(br));
return 0;
}
int ar[50]={1};
This will set only the first element to 1. Rest all will be 0.
memset(br, 1, sizeof(br));
This will set all the bytes in br to 1. It is not the same as setting all the values to 1. The values afterwards are:
{16843009, 16843009, 16843009, 16843009, 16843009}
Use memset when you know you really need it. It is not exactly made for initializing arrays, it just set the memory to a particular value.
Best way in C++? Use std::fill or std::fill_n.
Example:
int array[5];
std::fill(array, array + 5, 8);
Array now contains:
{8, 8, 8, 8, 8}
Using fill_n
std::fill_n(array, 5, 99);
Array now contains:
{99, 99, 99, 99, 99}
As a side note, prefer using std::array instead of c-style arrays.
Try on godbolt: https://godbolt.org/z/DmgTGE
References:
[1] : Array Initialization
[2] : memset doc
suppose you do
int ar[50] = {-1};
Now you will expect this line to initialize all array elements with -1
but it will not. It will only set the first element of array to -1 and rest to 0.
Whereas memset will show the expected behaviour.
See this Initialization of all elements of an array to one default value in C++? for more info.
let's take an example:-
int arr[5] = { 1, 2 }; // this will initialize to 1,2,0,0,0
int ar[5] = { }; // this will initialize all elements 0
int myArray[10] = {}; // his will also all elements 0 in C++ not in c
So If you want to initialize a specific value to an array use memset().
If you want to initialize all elements in an array to 0 use
static int myArray[10]; // all elements 0
Because objects with static storage duration will initialize to 0 if no initializer is specified and it is more portable than memset().
Also, The int ar[50]={0}; will be infinite because it just initializes the array and does not have an ending but in memset(arr,0,sizeof(br)) it has the correct way of ending the loop in arrays

Why does using push_back on a vector declared with size result in a vector of zeros?

I made a vector of constant size to store negative values, and then printing the values all I got was zeroes. I just want to know why it is not storing negative values.
#include <iostream>
#include <vector>
int main() {
std::vector<int> v(5);
v.push_back(-1);
v.push_back(-2);
v.push_back(-3);
v.push_back(-4);
v.push_back(-5);
for (int i=0; i<5; i++)
std::cout << v[i] << " "; // All I got was zeroes
}
That's because push_back puts new elements onto the end of the vector.
You can see the effect by running i to 9: the negative numbers will occupy v[5] to v[9].
Writing
std::vector<int> v{-1, -2, -3, -4, -5};
instead is a particularly elegant fix.
The constructor that you invoke fills the first 5 elements with zeros, see here (#3 in the list of overloads):
Constructs the container with count default-inserted instances of T
(where the "default-inserted instance" of an int is 0). What you might have wanted is
std::vector<int> v;
v.reserve(5); /* Prevent unnecessary allocations as you know the desired size. */
v.push_back(-1);
/* ... */
An alternative using the original constructor call is
#include <numeric>
std::vector<int> v(5);
std::iota(v.rbegin(), v.rend(), -v.size());
though this does more work than necessary as every element is first default constructed and then assigned to a new value again.
This is a case where the DRY principle would help you understand your mistake.
vector<int> v(5);
...
for(int i=0;i<5;i++)
Here you are creating an array, for which you think you reserve space for 5 elements. Then you insert those 5 elements. After that you wanted to print contents of the whole array, but instead of just writing v.size(), you repeated the 5, so that your code now reads like "Print first five elements of v", instead of "Print all elements of v".
If you instead wrote what you mean, you'd see that the array actually has 10 elements, not 5.
BTW, since C++11 you can loop over all elements in a more straightforward way:
for(int x : v)
or, if the elements were some more copy-expensive type, you could use references to the elements, even auto-type references:
for(auto& x : v)
This new for-loop syntax is called the range-based for loop.
You can consider the vector a flexible version of the primitive array in C/C++. When you initialize a vector with a size n, the constructed vector has size of n (or maybe larger in the memory, but you don't know since it's implicitly handled by compiler). Note that here n represents the number of entries, but not the actual memory usage (i.e. bytes). If you do not initialize it with a size parameter, the vector is empty with size 0, but in the memory it would have some implicit default memory size.
Let's say your current vector has size 5. And you want to push_back() in another element, then the vector internally will reallocate the entire array into a new memory location which could hold all its old entries plus the new one. So you don't need to reallocate the memory manually by yourself, like what you have to do in C.
Here, in your example, to fill in those 5 negative integers in your vector, there are a couple of ways.
1) You can initialize a vector without specifying the size. And then push in each element you want.
vector<int> v;
for (int i = -1; i >= -5; --i) {
v.push_back(i);
}
2) You can initialize the vector in your way with that size parameter. And then assign them with new values.
vector<int> v(5);
for (int i = 0; i < v.size(); ++i) {
v[i] = -i;
}
3) You can also initialize the vector with those entries when it is constructed.
vector<int> v{-1, -2, -3, -4, -5};
or vector<int> v = {-1, -2, -3, -4, -5};
When you declared the vector with
std::vector<int> v(5);
You made v store five 4-byte spaces in memory (assuming an int = 4 bytes on your system), and by default all of these 4-byte spaces store the bits representing 0's. Then, you pushed 5 more ints (-1, -2, -3, -4, -5) onto the end of the vector with:
v.push_back(-1);
v.push_back(-2);
v.push_back(-3);
v.push_back(-4);
v.push_back(-5);
At this point the vector has 10 elements, the first five being the unknown ints that happen to store 0's on the instance you ran the program. Since your for loop prints the first five elements in the vector, this is why it printed all 0's.
When you declared this line vector<int>v(5) it created a vector of size 5 with default value of all elements 0, at this stage your vector looks like this -
{0, 0, 0, 0, 0}
Now when you called v.push_back(-1) what it did is it pushed -1 to the back of vector increasing its size, now your vector looks like this -
{0, 0, 0, 0, 0, -1}
After every push back is performed your final vector will be - {0, 0, 0, 0, 0, -1, -2, -3, -4, -5}
The size of your vector is now increased to 10 from 5 and when you looped from index 0 to 4 it only printed 0. I hope I explained it well and fix for this is already provided in previous answers.

C++ insert 2-dimensional array of integer into another 2-dimensional array of integer

I want to insert 2-dimensional array into another 2-dimensional array- both are integer. The first one is smaller than the second then there is no error of size. The bigger have data for example to the middle of its own and second part has no data. I want to insert the second array in the middle of these data so that I need to push down the data in the bigger, meaning to copy non-zero part over the zero data.
It would be appreciated if someone could offer related code in the most efficient way.
for example:
int A[4][2] = {{1, 2} , {3, 4} , { 0, 0} , {0, 0} };
int B[2][2] = {{5, 6} , {7, 8}};
I want to insert B into A (between the first and second row) and push down the second row into the third row.
Then we have:
int A[4][2] = {{1, 2} ,{5, 6} , {7, 8} , {3, 4} };
I want to do this without using nested loop.
Arrays in C++ are FIXED SIZE -- so there's no way 'push down' data into an array, changing its size. You can only copy stuff, overwriting (part of) the destination array, but leaving it the same size.
If you want to do this, you need to either use something (like std::vector) that allows for a changing size, or create a NEW array of the desired size and copy the data into it:
int C[6][2];
std::copy(A, A+2, C);
std::copy(B, B+2, C+2);
std::copy(A+2, A+4, C+4);

c++ arrays, how to add a new row of values in the same array?

how do you create a new row of values in an array from user input or cin?
say theres a row of values already in the array and you need to add a second row of values
but not added to the first row, and how would you put the braces and the comma in, does the user put it in or is there something that will automatically put the bracers and comma in
int test [] = { 1, 21, 771, 410, 120711 },
{ 1, 2, 3, 4, 5 };
Without very bad and dirty tricks this is not possible. Better use list or vector (which is the nearest to an array). The other possibility is to use pointers and to extend it create a temporary memory, copy the old data and then add the new.
There is no way to change the size of array while still preserving its contents. The only way to change the size of an array at all is to use the new operator to allocate dynamic memory to a pointer, but this will destroy any data the array previously held. If you want to have a re-sizable array, you should probably use std::vector.
If you're keen on using c++11 you can keep your initialiser lists with std::vector like so:
#include <vector>
int main()
{
// initialise
std::vector<std::vector<int>> test = { { 1, 21, 771, 410, 120711 },
{ 1, 2, 3, 4, 5 } };
// add new data from user
test.push_back({9, 8, 7, 6, 5, 4, 3, 2, 1});
}
You're asking for a two-dimensional array. This is declared like this:
int test[][5] = {
{1, 21, 771, 410, 120711},
{1, 2, 3, 4, 5 },
// Add more if you want.
};
The first array is accessed through test[0], the second through test[1], etc. The first element of the first array is test[0][0], the second test[0][1] and so forth.
Note that this is an array with a static size. You can't change it at runtime. If you know in advance how many rows you need, you just declare it as:
int test[NUMBER OF ROWS][NUMBER OF COLUMNS];
and then fill it with values later. But you cannot change the size. If you want a fully dynamic array, then you should use a vector of vectors:
std::vector< std::vector<int> > test;
You then add rows with:
test.push_back(std::vector<int>());
and add elements to each row with:
// Adds a number to the first row.
test[0].push_back(some_int);
Access happens the same way as with the static array (test[0], test[0][0], etc.)

2-dimensional array, IF condition checking

I've came across a problem when coding with C++ 2D array.
Just a little question, what does the code below mean?
...
if(array[x][y] >= 9){
...
}
...
Does that mean when the sum of x and y of the array is greater or equal to 9, then only the body of the IF will run? Or ........?
Please explain and provide some simply examples.
the array is two dimensional, it means the element at array[x][y]
unlike 1D arrays, which only require 1 index, 2D arrays require 2 indices in the form of array[x][y] presumably in a nested for loop.
You can iterate through such an array like this
for (int x = 0; x < arrayLength; x++) {
for (int y = 0; y < array[x]Length; y++) {
// do something with array[x][y]
}
}
where arrayLength is the length of array and array[x] length is the length of array[x].
So in reference to the code that you posted, it's testing to see if the member of the 2D array is greater than or equal to 9.
Ok let's start with the basics.
1D Arrays
How can you imagine a normal array? You could say a normal array is like a number line:
|-------------------------------| where every - is one element in your array
The very first '-' on the left side is the element at myArray[0] (the '|' are just symbolizing that it has a start and a end).
2D Arrays
A 2D array can be visualized as checkerboard, bookshelf or a table with columns and rows.
|-------------------------------|
|-------------------------------|
|-------------------------------|
|-------------------------------|
Just like in chess you need 2 values in order to address an element. If you only specify one value the compiler might know the row of your value but not its column (or the other way around). That means you need x and y coordinates (which is a visual analogy for a coordinate system). In order to address a value you have to do it like this:
myArray[x][y] where x could be the row of our checkerboard and y the column.
In your case your 2D array is most likely filled with integers. The 'if' statement checks if the value stored in myArray[x][y] is larger than 9. If myArray[x][y] is larger than 9 this statement returns true and the code inside will get executed.
After executing the code inside of the 'if' statement the program will continue to execute the code after the if statement. 2D arrays can be understood as an array containing arrays.
If you are thinking 3 dimensional arrays are possible you're right. Here you need 3 coordinates in order to describe a point since you have depth, height and length (here I'm talking about the visual length not the length in terms of total amount of elements.).
I don't know whether this helped but this is of course a very visual approach of explaining how multi-dimensional arrays work.
Example
int myArray[3][3] = {{1, 2, 3}, // row 0
{4, 5, 6}, // row 1
{7, 8, 10}}; // row 2
In this case your if statement would only be executed if x = 2 and y = 2 since myArray[2][2] = 10
It means "IF the element at coordinates (x,y) is greater or equal than 9...".
There is no addition operation. The array is probably declared with the minimum dimensions (x+1, y+1).
int array[2][2] = {{12, 6}, {3, -2}};
int x=1, y=0;
if(array[x][y] >= 9){...} // array[1][0] equals 3, condition is false