If all your elements are positive integers, one simple (if inefficient) way is to find the maximum element, make an array of that size of all zeros using calloc()
or similar, and use that array as a perfect hash table:
int
find_max(int* arr, size_t len)
{
int max = INT_MIN;
for (size_t idx = 0; idx < len; idx++)
max = (arr[idx] > max) ? arr[idx] : max;
return max;
}
int*
make_hash_table(size_t len)
{
return calloc(len, sizeof(int));
}
void
free_hash_table(int** ht)
{
free(*ht), *ht = NULL;
}
int*
make_filtered_array(int* arr, size_t len, int* ht)
{
int* new_arr = malloc(len * sizeof(int));
for (size_t idx = 0; idx < len; idx++) {
new_arr[idx] = (ht[arr[idx]] == 0) ? arr[idx] : 0;
ht[arr[idx]] = 1;
}
return new_arr;
}
In your main function, you might then do something like:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int
main()
{
int foo[] = {5, 2, 3, 4, 3, 6};
/* calculate length of static foo -- does not work for dynamic arrays */
size_t foo_length = sizeof(foo)/sizeof(*foo);
/* find maximum element in foo */
int foo_max = find_max(foo, foo_length);
/* make an int array of size foo_max that contains all zeroes, to use as a hash table */
int* hash_table = make_hash_table(foo_max);
/* make an int array containing filtered values */
int* filtered_array = make_filtered_array(foo, foo_length, hash_table);
/* print the filtered array */
for (size_t idx = 0; idx < foo_length; idx++)
fprintf(stdout, "%d ", filtered_array[idx]);
fprintf(stdout, "\n");
/* clean up dynamically-allocated memory */
free_hash_table(&hash_table);
free(filtered_array);
return EXIT_SUCCESS;
}
Given input of {5, 2, 3, 4, 3, 6}
, the printed output is:
5 2 3 4 0 6
If there are negative integers, you can still use this approach with some tweaks to the lookup table. I'll let you think about how to do that.
This should run in time linearly proportional to the size of the input array, because finding the maximum element in your input array is linear (you walk through the whole array once) and lookups to the hash table are in constant time.
On a first pass, this is not memory efficient. For an array of size n
, you need two more arrays of size n
. If you can replace the static array foo[]
with a dynamic array, however, you can replace elements in that input array in-place, without creating a duplicate array. I'll let you think about how to do that.