1

I have an array like the following

int arr[32];

This array can contain 32 element.
If I added into that array some data like the following

arr[0] = 5;
arr[1] = 10;
arr[2] = 15;
arr[3] = 20;

As you see I added data into elements 0,1,2,3 and the other elements is still not initialized or empty.

Now, how to get the elements count that has only data ?

in current example will get 4 elements.

Lion King
  • 32,851
  • 25
  • 81
  • 143
  • (1) Initialize the array with a known value (typically, 0). Then check how many are not your starting value. (2) Keep an "nUsed" variable and increment it per write. (3) Create a parallel array containing booleans for 'used' elements. ..There must be more ways.. – Jongware Nov 17 '13 at 10:54
  • (4) If you plan to add elements *in* order, all you need is to keep the "next" index to be filled in; (5) for *out of order*, any of the above, or a parallel in-order list that keeps a list of assigned indices (this itself would be an in-order array). – Jongware Nov 17 '13 at 11:10
  • (For (6) see comment in @NemanjaBoric's answer) (7) Your new values all match the pattern `n > 0 && n % 5 == 0`. Initialize the array with values that do not match this pattern. If you need to find how many elements are used, test each value against your pattern. – Jongware Nov 17 '13 at 11:59
  • (8) Make a list of allowed values. In `arr` you store the *index* of an allowed value. Members of `arr` that do not point to a valid index in the `allowed` array, or point to an index in the `allowed` array that is designated as "invalid" are not used. – Jongware Nov 17 '13 at 12:16
  • (9) Make a list of allowed values. Initialize your array with any value not in this list. To count "used" elements, compare each value against the `allowed` list. – Jongware Nov 17 '13 at 12:19

3 Answers3

3

You could do this in multiple ways - one is to keep counter of initialized values:

arr[0] = 5;
arr[1] = 10;
arr[2] = 15;
arr[3] = 20;
n = 4;

This only works if you will fill array sequentially.

Other way is to initialize array with some value which semantically can't be elements of the array:

int arr[32] = {-1};

After that, you can check if the current element contains value different than -1.

The sample loop could be implemented like this:

for(i = 0; i < 32 && arr[i] != -1; i++)
{
   // do things
}

Also, as @Jongware pointed out in the comment - if you don't mind spending O(n) of extra space - you could have additional flag array:

int fill[32] = {0};
arr[0] = 5;   fill[0] = 1;
arr[1] = 10;  fill[1] = 1;
arr[2] = 15;  fill[2] = 1;
arr[3] = 20;  fill[3] = 1;

You could save some space using bitsets, if that is important for you.

Nemanja Boric
  • 21,627
  • 6
  • 67
  • 91
  • Unfortunately [C does not support operator overloading](http://stackoverflow.com/questions/10624525/is-it-possible-to-overload-operators-in-c). I was thinking of adding "overload the `[]` operator" ... – Jongware Nov 17 '13 at 11:00
  • Thanks for answer, but the problem is, when I make a code to loop to print the elements that has a data only, `for(i=0; i < what should I write here; i++)`. – Lion King Nov 17 '13 at 11:17
  • @LionKing: "a data" -- no! An array *always* contains data! – Jongware Nov 17 '13 at 11:21
  • Sorry, I mean the elements which have a value assigned like the elements [0,1,2,3]. – Lion King Nov 17 '13 at 11:24
  • `for(i = 0; i < 32 && arr[i] != -1; i++)`. what is the meaning of this part `32 && arr[i]`. – Lion King Nov 17 '13 at 11:28
  • keeping a value ( like -1 in this case) as a reference to an unfilled array space does not work out. What if the user wants value -1 in his array – Andy Stow Away Nov 17 '13 at 11:28
  • 1
    @AndyStowAway: Nemanja says "which **semantically** can't be elements of the array". So if -1 is *semantically* allowed, pick a value that is not. (+1, for example.) – Jongware Nov 17 '13 at 11:49
  • 1
    It gave me an idea for (6), though: initially, choose a *random* "invalid" value and fill the array with that. When assigning a value, check if it is `invalidNumber` -- if it is, pick another one (not already in the list) and change all `invalidNumber` elements to this new one before assigning the new number. – Jongware Nov 17 '13 at 11:55
  • @LionKing you have two conditions - first is `i < 32` - if all elements are "filled" so you can't go outside of array. The second is `arr[i] != -1` - loop until you find first "invalid" element. Using operator `&&` (logical `AND`) you will loop as long as both conditions are evaluating to true. – Nemanja Boric Nov 17 '13 at 12:07
  • @NemanjaBoric: you're welcome. Want to help and try to find *10* different ways? – Jongware Nov 17 '13 at 12:12
1
int arr[32]={0};
int c=0;
arr[0] = 5;
arr[1] = 10;
arr[2] = 15;
arr[3] = 20;
for(int i=0; i<32; i++){
    if(arr[i]){
            c=c+1;
              }
printf("count is %d",c);
}
0

This is how I'd keep a strict list of possibly assigned elements. This creates a write-once array.

int arr[32];

int assignedOrder[32];
int assignedOrderIndex = 0;

int assign (int index, value)
{
   int i;
   if (index < 0 || index >= 32)
     return E_FAIL;
   if (assignedOrderIndex == 32)
     return E_FAIL;
   for (i=0; i<assignedOrderIndex; i++)
     if (assignedOrder[i] == index)
       return E_FAIL;
   arr[index] = value;
   assignedOrder[assignedOrderIndex] = index;
   assignedOrderIndex++;
   return E_SUCCESS;
}

Somehow this feels like maybe you should step over to C++, as there are standard objects that have precisely this function.

Jongware
  • 22,200
  • 8
  • 54
  • 100