4

Instead of looping through each element of an array is it possible to loop through only elements which have assignments?

In the following example I would like to loop through only three elements instead of looping through each element in the array. What are my options ? I hate to loop through thousands of elements when only handful from them are assigned based on certain logic.

main()
{
    int i, intArray[10000];
    intArray[334] = 30;
    intArray[563] = 50;
    intArray[989] = 90;

    for (i = 0; i < 10000; i++)
    {
      printf("%d\n", intArray[i]);
    }
}

Thank you for reading the post. Sorry if it a re-post. I would not find similar question in the forum.

2
  • 4
    Google "sparse arrays" Commented Sep 7, 2013 at 4:07
  • 1
    Is this for performance, or just to avoid printing so much? Is there a value you could consider to be invalid? If the problem is just printing a lot, if you had an invalid value, you could do, if (intArray[i] == invalidVal) { continue; } Commented Sep 7, 2013 at 4:10

3 Answers 3

6

Only indirectly:

#include <stdio.h>

int main(void)
{
    int i, intArray[10000];
    int active[10000];
    int n_active = 0;
    intArray[334] = 30;
    active[n_active++] = 334;
    intArray[563] = 50;
    active[n_active++] = 563;
    intArray[989] = 90;
    active[n_active++] = 989;

    for (i = 0; i < n_active; i++)
      printf("%d\n", intArray[active[i]]);
    return 0;
}

Or, more succinctly but not more clearly:

#include <stdio.h>

int main(void)
{
    int i, intArray[10000];
    int active[10000];
    int n_active = 0;
    intArray[active[n_active++]=334] = 30;
    intArray[active[n_active++]=563] = 50;
    intArray[active[n_active++]=989] = 90;

    for (i = 0; i < n_active; i++)
      printf("%d\n", intArray[active[i]]);
    return 0;
}

Both of these programs will suffer if there's more than one assignment to the same index (that index will be stored in the active array twice). As it stands, it also doesn't check for overflow of the active array (but that shouldn't be a problem; the hypothesis is that only a few of the rows are populated), and the indexes are stored in the order that they're presented — not in key order. All these defects can be fixed, but take more code (it would probably need to be a function or two).

Sign up to request clarification or add additional context in comments.

Comments

1

You can do something like this

# include <stdio.h>
int totalElements = 0;
struct 
{
   int index, data;
} Data[10000];

void addElement(int index, int data)
{
   Data[totalElements].data = data;
   Data[totalElements++].index = index;
}

main()
{
   int i;
   addElement(334, 30);
   addElement(563, 50);
   addElement(989, 90);
   for (i = 0; i < totalElements; i++)
   {
      printf("%d %d\n", Data[i].data, Data[i].index);
   }
}

Output

30 334
50 563
90 989

This also suffers the same limitations Jonathan Leffler mentioned.

EDIT

# include <stdio.h>
int totalElements = 0;
struct
{
   int index, currentElement = 0, data[100];
} Data[10000];

void addElement(int index, int data)
{
   int i;
   for (i = 0; i < totalElements; i++)
   {
      if (Data[i].index == index)
      {
         Data[i].data[Data[i].currentElement++] = data;
         return;
      }
   }
   Data[totalElements].data[Data[totalElements].currentElement++] = data;
   Data[totalElements++].index = index;
}

main()
{
   int i, j;
   addElement(334, 30);
   addElement(334, 40);
   addElement(563, 50);
   addElement(563, 60);
   addElement(989, 80);
   addElement(989, 90);
   for (i = 0; i < totalElements; i++)
   {
      for (j = 0; j < Data[i].currentElement; j++)
      {
         printf("%d %d\n", Data[i].index, Data[i].data[j]);
      }
   }
}

Output

334 30
334 40
563 50
563 60
989 80
989 90

Using this idea you can overcome the limitations mentioned by Jonathan Leffler.

2 Comments

I like your first solution, but the edit solves the wrong problem. To resemble the simple array from the question, it should just overwrite the value in a specific position instead of inserting it in order. Besides, maybe you should mention that the second solution uses 101 times more memory than the original.
The limitation Jonathan mentioned was same indices storing multiple values. I believe that is what the second solution solves.
0

Perhaps you could use a different data structure, like a linked list. Each node in the list could have two int values, one could be the index and the other the value. The linked list would then only contain indicies which have been assigned (and you could also have value==0, if that is somehow different to the normal, unassigned index).

The other alternative would be to use something like a Dictionary structure. There are probably Dictionary implementations for C - I would say though, if C++ is available maybe you should use it instead (unless you are specifically trying to learn or are constrained to C) - C++ has many data types available straight out of the box.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.