What is the ideal way to make a unique list of values in C?
Say we have
typedef struct {
int value1;
int value2;
} values_t;
and
values_t* values;
is filled with values[i].value1 and values[i].value2 pairs that may or may not be unique.
and we want to fill
values_t* values_unique;
only with unique pairs from values, in the order they first appear in values.
What is the ideal way to do this in C?
EDIT: Assume they are properly ma开发者_JS百科lloced pointers; above is just pseudo code.
You probably use a hash of the values, maintaining a list of the hashes and the corresponding values, and only add a new pair to the values_unique
array (which the question does originally did not declare as an array) if it is not found via the hash. If the list is large, the speed up from hashing instead of searching through the entire list sequentially can be quite significant.
It'll be something like this (Haven't been coding in C for long time, and code isn't tested):
#include<stdlib.h>
#include<stdio.h>
typedef struct {
int value1;
int value2;
} values_t;
values_t* values;
size_t values_size = 100;
values_t* values_unique;
size_t values_unique_size;
int valcmp(const values_t* a, const values_t* b)
{
//a < b -> -1
//a == b -> 0
//a > b -> 1
return (a->value1 == b->value1) ? ((a->value2 == b->value2) ? 0 : ((a->value2 < b->value2) ? -1 : 1)) : ((a->value1 < b->value1) ? -1 : 1);
}
int main(void)
{
values = malloc(values_size * sizeof(values_t));
values_unique = malloc(values_size * sizeof(values_t));
//fill the values table
memcpy(values_unique, values, values_size * sizeof(values_t));
qsort(values_unique, values_size, sizeof(values_t), valcmp);
int i;
//hopefully values_size > 0
for(i = 1, values_unique_size = 1; i < values_size; ++i)
if(valcmp(&values_unique[i], &values_unique[values_unique_size - 1]) != 0)
values_unique[values_unique_size] = values_unique[i];
}
Same in c++:
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
vector<pair<int,int> > V, V_unique;
int main()
{
V_unique = V;
sort(V_unique.begin(), V_unique.end());
V_unique.resize(unique(V_unique.begin(), V_unique.end()) - V_unique.begin());
}
I know it's fairly annoying to suggest a different language but using C++ stl would be trivial.
set<values_t> mySet();
for(int i=0; i < number_of_values; i++)
{
mySet.insert(values[i]);
}
values_t * values_unique = new values_t[mySet.size()];
int j=0;
for(set<values_t>::iterator i = mySet.begin(); mySet.end() != i; i++)
{
values_unique[j] = *i;
j++
}
精彩评论