Count the number of initialized elements in an array in C - c

My array is:
int array[100];
If I initialize the first n elements (n < 100) with integers including 0, and the rest is uninitialized, how do I calculate n?
I tried a normal while loop with the following codes:
int i = 0;
int count = 0;
while (a[i++])
count++;
However, the problem with these codes is that it doesn't count the element of value 0 (it takes 0 as FALSE). How do I overcome this problem?
UPDATE: below is the background of this question
I have the following code:
int a[100];
int i;
for (i = 0; i < 100; i++)
scanf("%d", &a[i]);
If I have to input (just an example):
1 0 1 0 1 *
Then the first 5 elements of the array will be: 1 0 1 0 1. The rest will be uninitialized. In this situation, how do I count the number of these initialized elements to get 5?

If you can't simply record how many elements have been initialized, then you need to use a "magic" value like INT_MIN (the largest negative int) to know when an element is not used. Alternatively, instead of storing ints, store something like this:
struct element {
int value;
int flags; // 0 means not used
};
Oh, one more idea: store the count of initialized elements in the first element. This is sort of how malloc() works sometimes. Then you can make the array have 101 elements and pass (array + 1, array[0]) to functions which expect an array of size 100.

Related

how to find the number of elements present in an array in C

suppose I have an array a[10] and it is filled up to 6 places example a[]={10,20,30,40,50,60} now rest 4 places are empty, now how do I print the number of places that are filled in an array-like in the above case it should print 6, given the scenario that I do not know the array beforehand like I do not have any clue what size it is or the elements that are there inside.
int a[]={10,20,30,40,50,60} initilizes all 6 elements.
int b[10]={10,20,30,40,50,60} initilizes all 10 elements, the last ones to 0.
There is no partial initialization in C.
There is no specified "empty".
to find the number of elements present in an array in C
size_t elemnt_count_a = sizeof a / sizeof a[0]; // 6
size_t elemnt_count_b = sizeof b / sizeof b[0]; // 10
I do not know the array beforehand
In C, when an array is defined, its size is known.
if the array is a[]={10,20,30,40,50,60}
here is my psedocode -
int size = 0;
if(i = 0; i < a.length(); i++) {
if(a[i] != null)
size++
}
the value of size should print 6

Fastest data structure for inserting billions of integers?

I want recommendation on which is the fastest data structure in C which can hold about 2 billion integers taken from input. The integer value would not be less than 0 and would not be greater than 2 billion. My goal is to remove any duplicate values and sort elements of the data structure. If possible, I want to able to do the inserting operation in O(1) or O(logn) or as quickly as possible. I also want to avoid trees if possible. I would appreciate any feedback or recommendation about this.
Edit: Using a normal array would take a really long time. So, I want to use some other data structure than the array such as stack, queue, etc.
Since you have a given number of values, and the range of those values is the same as the number of values, you can implement the list as an array where each array index represents a value and the value of each array element represents whether or not a given value is in the list.
For example:
char *arr = malloc(20000000001);
int i;
// populate list
memset(arr, 0, sizeof(arr));
for (i=0; i<20000000001; i++) {
int value;
scanf("%d", &value);
arr[value] = 1;
}
// print list
for (i=0; i<20000000001; i++) {
if (arr[i]) {
printf("%d\n", i);
}
}
Here we initialize the list to contain 0 for all values. Then we read in the values. If we read the value n, then we set arr[n] to 1. This does two things: it inserts the value in the list and eliminates duplicates by always setting the value to 1 as opposed to incrementing the value.
This gives O(1) insersions with duplicate removal, and the list is already sorted.
Note also that since each element of the array only needs to store the values 0 or 1 we cause use char as the type to save memory. We can further save memory if we use each bit to hold the value 0 or 1 for a given value. Doing this will involve some bit shifting:
unsigned char *arr = malloc(20000000001 / 8 + 1);
int i;
// populate list
memset(arr, 0, sizeof(arr));
for (i=0; i<20000000001; i++) {
int value;
scanf("%d", &value);
arr[value/8] |= 1 << (value%8);
}
// print list
for (i=0; i<20000000001; i++) {
if (arr[i/8] & (1 << (i%8))) {
printf("%d\n", i);
}
}
This cuts the memory requirements down to about 250MB which is still large but manageable.

developing a function that returns number of distinct values that exist in array

I want to create a function that can return the number distinct values present in a given array. If for eg the array is
array[5] = { 1 3 4 1 3}, the return value should be 3(3 unique numbers in array).
I've so far only got this:
int NewFucntion(int values[], int numValues){
for (i=0; i<numValues; i++){
Im a new coder/New to C language and im stuck on how to proceed. Any guidance would be much appreciated. Thanks
Add elements from the array to the std::set<T> and since the set is not allowing duplicate elements, you can then only get the number of elements from the set which gives you the number of distinct elements.
For example:
#include<set>
int NewFucntion(int values[], int numValues){
std::set<int> set;
for(int i=0; i<numValues; i++){
set.insert(values[i]);
}
return set.size();
}
int distinct(int arr[], int arr_size){
int count = arr_size;
int current;
int i, j;
for (i = 0; i < arr_size; i++){
current = arr[i];
for (j = i+1; j < arr_size; j++) // checks values after [i]th element.
if (current == arr[j])
--count; // decrease count by 1;
}
if (count >= 0)
return count;
else return 0;
}
Here's the explanation.
The array with its size is passed as an argument.
current stores the element to compare others with.
count is the number that we need finally.
count is assigned the value of size of the array (i.e we assume that all elements are unique).
(It can also be the other way round)
A for loop starts, and the first (0th) element is compared with the elements after it.
If the element reoccurs, i.e. if (current==arr[j]), then the value of count is decremented by 1 (since we expected all elements to be unique, and because it is not unique, the number of unique values is now one less than what it was initially. Hence --count).
The loops go on, and the value is decremented to whatever the number of unique elements is.
In case our array is {1,1,1,1}, then the code will print 0 instead of a negative value.
Hope that helps.
Happy coding. :)
I like wdc's answer, but I am going to give an alternative using only arrays and ints as you seam to be coding in c and wdc's answer is a c++ answer:
To do this thing, what you need to do is to go through your array as you did, and store the new numbers you go over in a different array lets call it repArray where there wont be any repetition; So every time you add something to this array you should check if the number isn't already there.
You need to create it and give it a size so why not numValues as it cannot get any longer than that. And an integers specifying how many of it's indexes are valid, in other words how many you have written to let's say validIndexes. So every time you add a NEW element to repArray you need to increment validIndexes.
In the end validIndexes will be your result.

Segmentation fault in test cases

So, the question is as follows:
Given any array(reasonably large) of integers, return the maximum difference between any two elements in the array such that the larger element occurs at a higher index than the smaller element. Return -1, if no such pair is found.
Example:
7
2
3
10
2
4
8
1
where the first element is the size of the array(or the number of lines being entered), and the rest are the elements.
Sample output is 8(10-2) for the above.
My code is as follows:
int A[20],size;
scanf("%d",&size);
for(int i=0;i<size;i++){
scanf("%d\n",&A[i]);
}
int diff = A[1]-A[0];
int currsum = diff;
int maxsum = currsum;
for(int i=1; i<size-1; i++)
{
// Calculate current difference for the loop
diff = A[i+1]-A[i];
// Calculate current sum for the loop
if (currsum > 0)
currsum += diff;
else
currsum = diff;
// Update max sum(if needed)
if (currsum > maxsum)
maxsum = currsum;
}
printf("%d",maxsum);
This is a question from Hackerrank, but it runs for only three out of 10 possible testcases. The rest of the cases return a segmentation fault. Any idea would be helpful.
As mentioned in the comments, you've declared A to hold just 20 integers. But the question can send up to 1,000,000 integers. That's the mistake!
Using pointers make this more important. First declare A as pointer of integers, then, read the first element of the array, using this integer you can allocate memory dynamically (malloc() or calloc() function) for your array A. so the size of A will dynamic and you can resize it in function of the first element.

Initializing entire 2D array with one value

With the following declaration
int array[ROW][COLUMN]={0};
I get the array with all zeroes but with the following one
int array[ROW][COLUMN]={1};
I don’t get the array with all one value. The default value is still 0.
Why this behavior and how can I initialize with all 1?
EDIT: I have just understood that using memset with value as 1, will set each byte as 1 and hence the actual value of each array cell wont be 1 but 16843009. How do I set it to 1?
You get this behavior, because int array [ROW][COLUMN] = {1}; does not mean "set all items to one". Let me try to explain how this works step by step.
The explicit, overly clear way of initializing your array would be like this:
#define ROW 2
#define COLUMN 2
int array [ROW][COLUMN] =
{
{0, 0},
{0, 0}
};
However, C allows you to leave out some of the items in an array (or struct/union). You could for example write:
int array [ROW][COLUMN] =
{
{1, 2}
};
This means, initialize the first elements to 1 and 2, and the rest of the elements "as if they had static storage duration". There is a rule in C saying that all objects of static storage duration, that are not explicitly initialized by the programmer, must be set to zero.
So in the above example, the first row gets set to 1,2 and the next to 0,0 since we didn't give them any explicit values.
Next, there is a rule in C allowing lax brace style. The first example could as well be written as
int array [ROW][COLUMN] = {0, 0, 0, 0};
although of course this is poor style, it is harder to read and understand. But this rule is convenient, because it allows us to write
int array [ROW][COLUMN] = {0};
which means: "initialize the very first column in the first row to 0, and all other items as if they had static storage duration, ie set them to zero."
therefore, if you attempt
int array [ROW][COLUMN] = {1};
it means "initialize the very first column in the first row to 1 and set all other items to zero".
As for how to initialize the whole array to a specific value/values, see https://stackoverflow.com/a/13488596/584518.
If you want to initialize the array to -1 then you can use the following,
memset(array, -1, sizeof(array[0][0]) * row * count)
But this will work 0 and -1 only
int array[ROW][COLUMN]={1};
This initialises only the first element to 1. Everything else gets a 0.
In the first instance, you're doing the same - initialising the first element to 0, and the rest defaults to 0.
The reason is straightforward: for an array, the compiler will initialise every value you don't specify with 0.
With a char array you could use memset to set every byte, but this will not generally work with an int array (though it's fine for 0).
A general for loop will do this quickly:
for (int i = 0; i < ROW; i++)
for (int j = 0; j < COLUMN; j++)
array[i][j] = 1;
Or possibly quicker (depending on the compiler)
for (int i = 0; i < ROW*COLUMN; i++)
*((int*)a + i) = 1;
To initialize 2d array with zero use the below method:
int arr[n][m] = {};
NOTE : The above method will only work to initialize with 0;
Note that GCC has an extension to the designated initializer notation which is very useful for the context. It is also allowed by clang without comment (in part because it tries to be compatible with GCC).
The extension notation allows you to use ... to designate a range of elements to be initialized with the following value. For example:
#include <stdio.h>
enum { ROW = 5, COLUMN = 10 };
int array[ROW][COLUMN] = { [0 ... ROW-1] = { [0 ... COLUMN-1] = 1 } };
int main(void)
{
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COLUMN; j++)
printf("%2d", array[i][j]);
putchar('\n');
}
return 0;
}
The output is, unsurprisingly:
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
Note that Fortran 66 (Fortran IV) had repeat counts for initializers for arrays; it's always struck me as odd that C didn't get them when designated initializers were added to the language. And Pascal uses the 0..9 notation to designate the range from 0 to 9 inclusive, but C doesn't use .. as a token, so it is not surprising that was not used.
Note that the spaces around the ... notation are essentially mandatory; if they're attached to numbers, then the number is interpreted as a floating point number. For example, 0...9 would be tokenized as 0., ., .9, and floating point numbers aren't allowed as array subscripts.
With the named constants, ...ROW-1 would not cause trouble, but it is better to get into the safe habits.
Addenda:
I note in passing that GCC 7.3.0 rejects:
int array[ROW][COLUMN] = { [0 ... ROW-1] = { [0 ... COLUMN-1] = { 1 } } };
where there's an extra set of braces around the scalar initializer 1 (error: braces around scalar initializer [-Werror]). I'm not sure that's correct given that you can normally specify braces around a scalar in int a = { 1 };, which is explicitly allowed by the standard. I'm not certain it's incorrect, either.
I also wonder if a better notation would be [0]...[9] — that is unambiguous, cannot be confused with any other valid syntax, and avoids confusion with floating point numbers.
int array[ROW][COLUMN] = { [0]...[4] = { [0]...[9] = 1 } };
Maybe the standards committee would consider that?
Use vector array instead:
vector<vector<int>> array(ROW, vector<int>(COLUMN, 1));
char grid[row][col];
memset(grid, ' ', sizeof(grid));
That's for initializing char array elements to space characters.

Resources