For loop with the length of array that has values - c++

Say I have an integer array called abc[100]. abc only has values in the first 5 "slots". How can I write a for loop for this where the loop goes up until the last value in abc that isnt empty?
int abc[100] = {1, 2, 3, 4, 5};

In C++ arrays, there is no concept of an array element being "empty".
That idea simply doesn't exist. Erase it from your mind.
Each array element always exists.
In C & C++, when part of an array is explicitly initialized, and part is not explicitly initialized, the part that you didn't specify defaults to zero.
So, you effectively wrote:
int abc[100] = {1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0....};
If you want, you can treat value 0 as a marker for values that aren't set.
int i;
for(i=0; abc[i] != 0; ++i)
{
cout << "[" <<i<< "] : " << abc[i] <<endl;
}

In C++ if you declare an array and initialize only the first few elements, the remaining elements will be value initialize, meaning basically that the "default constructor" will be called.
For built-in types such as int value initializing sets the value to zero. So if you fix the problems with your array, and only initialize the first five elements the remaining will be initialized to zero.

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.

Find runs of consecutive values in int array

Let's say I have this integer array of separate integer elements:
111100010011010
I'd like to find out if there exists 0000 in this array, which obviously does not, but 000 exists. Same goes for other lengths of consecutive runs.
I know this is easily done with strings, there are built in functions for this, but is there something built in which accomplishes what I want to do?
Or is there another easy method I overlooked? All I can come up with are complicated non efficient algorithms going through the array and saving values in a temporary other array.
No need to save values to a temporary array.
All you need to do is keep track of the largest length found (initially zero) and the location of its first element (initially NULL if you use a pointer to indicate that).
Then walk through the array until you find the value of interest. Count the number of consecutive occurrences. If that number exceeds the maximum length found, set the location to point at the first one found.
Repeat until end of array is reached.
Done. If the largest length found is zero, it means there were no occurrences of the value sought.
No, I'm not going to write code for the above. The description of the approach is enough.
There are also plenty of alternative options using standard algorithms
Just for the record, another way is to use use std::search.
#include <algorithm>
using namespace std;
const int elements[] = { 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0 };
const int test1[] = { 0, 0, 0, 0 };
const int test2[] = { 0, 0, 0 };
auto it1 = std::search(begin(elements), end(elements), begin(test1), end(test1));
auto it2 = std::search(begin(elements), end(elements), begin(test2), end(test2));
std::cout << "Test 0000: " << (it1 == end(elements) ? "no" : "yes") << "\n";
std::cout << "Test 000: " << (it2 == end(elements) ? "no" : "yes") << "\n";
Prints out:
Test 0000: no
Test 000: yes
Even easier if your array is a standard container, like std::array or vector.

Bijective mapping of integers

English is not my native language: sorry for my mistakes. Thank you in advance for your answers.
I'm learning C++ and I'm trying to check to what extent two sets with the same number of integers--in whatever order--are bijective.
Example :
int ArrayA [4] = { 0, 0, 3, 4 };
int ArrayB [4] = { 4, 0, 0, 3 };
ArrayA and ArrayB are bijective.
My implementation is naive.
int i, x=0;
std::sort(std::begin(ArrayA), std::end(ArrayA));
std::sort(std::begin(ArrayB), std::end(ArrayB));
for (i=0; i<4; i++) if (ArrayA[i]!=ArrayB[i]) x++;
If x == 0, then the two sets are bijective. Easy.
My problem is the following: I would like to count the number of bijections between the sets, and not only the whole property of the relationship between ArrayA and ArrayB.
Example :
int ArrayA [4] = { 0, 0, 0, 1 }
int ArrayB [4] = { 3, 1, 3, 0 }
Are the sets bijective as a whole? No. But there are 2 bijections (0 and 0, 1 and 1).
With my code, the output would be 1 bijection. Indeed, if we sort the arrays, we get:
ArrayA = 0, 0, 0, 1;
ArrayB = 0, 1, 3, 3.
A side-by-side comparaison shows only a bijection between 0 and 0.
Then, my question is:
Do you know a method to map elements between two equally-sized sets and count the number of bijections, whatever the order of the integers?
Solved!
The answer given by Ivaylo Strandjev works:
Sort the sets,
Use the std::set_intersection function,
Profit.
You need to count the number of elements that are contained in both sets. This is called set intersection and it can be done with a standard function - set_intersection, part of the header algorithm. Keep in mind you still need to sort the two arrays first.

Initializing arrays in C++

I'm trying to initialize the last element in the array
int grades[10];
to grade 7 but it doesn't seem to work
I'm using C++ btw
If you want to initialize them all at definition:
int grades[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 7 };
If you want to initialize after:
int grades[10];
grades[9] = 7;
But, be aware that grades 0..8 will still be uninitialized, and will likely be junk values.
One more thing, if you initialize only the first element (if explicit array size is specified) or a shorter initiliazation list, the unspecified elements are fill with 0. E.g.
int grades[10] = {8}; //init with one element
is the same as:
int grades[10] = { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
or
int grades[10] = { 1, 9, 6, 16 }; //or init with a shorter than array size list with a minimum of 1 element
is the same as:
int grades[10] = { 1, 9, 6, 16, 0, 0, 0, 0, 0, 0 };
I find it handy for initializing an array with 0 values.
float coefficients[10] = {0.0f}; //everything here is full of 0.0f
when You write something like
int a[5] = {0};
it sets the whole array to zero on the contrary
int a[5] = {3};
sets only the first element and the rest may be anything(garbage values);
if You want to set the whole array with some value then u can go for the
std :: fill()
something like this
std::fill(arr, arr+100, 7); // sets every value in the array to 7
and if there is a character array You can always go for the memset function
The last element is grades[9], since arrays in C++ are zero-based (e.g. grades[0] to grades[9] are 10 elements). Is that what you're doing?
You might need to subtract one from the grade to use as your subscript value, or set the extent to one more.
Remember that an array with ten elements will have grades[0] through grades[9], and that grades[10] is an error.