Sort a list of object identifiers: Difference between revisions
Content added Content deleted
(Added C solution) |
|||
Line 100: | Line 100: | ||
{{out}} |
{{out}} |
||
<pre>1.3.6.1.4.1.11.2.17.5.2.0.79 |
<pre>1.3.6.1.4.1.11.2.17.5.2.0.79 |
||
1.3.6.1.4.1.11.2.17.19.3.4.0.1 |
|||
1.3.6.1.4.1.11.2.17.19.3.4.0.4 |
|||
1.3.6.1.4.1.11.2.17.19.3.4.0.10 |
|||
1.3.6.1.4.1.11150.3.4.0 |
|||
1.3.6.1.4.1.11150.3.4.0.1 |
|||
</pre> |
|||
=={{header|C}}== |
|||
A C99 (or later) compiler is required. |
|||
<lang cpp>#include <stdio.h> |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
typedef struct oid_tag |
|||
{ |
|||
char* str_; |
|||
int* numbers_; |
|||
int length_; |
|||
} oid; |
|||
// free memory, no-op if p is null |
|||
void oid_destroy(oid* p) |
|||
{ |
|||
if (p != 0) |
|||
{ |
|||
free(p->str_); |
|||
free(p->numbers_); |
|||
free(p); |
|||
} |
|||
} |
|||
int char_count(const char* str, char ch) |
|||
{ |
|||
int count = 0; |
|||
for (const char* p = str; *p; ++p) |
|||
{ |
|||
if (*p == ch) |
|||
++count; |
|||
} |
|||
return count; |
|||
} |
|||
// construct an OID from a string |
|||
// returns 0 on memory allocation failure or parse error |
|||
oid* oid_create(const char* str) |
|||
{ |
|||
oid* ptr = calloc(1, sizeof(oid)); |
|||
if (ptr == 0) |
|||
return 0; |
|||
ptr->str_ = strdup(str); |
|||
if (ptr->str_ == 0) |
|||
{ |
|||
oid_destroy(ptr); |
|||
return 0; |
|||
} |
|||
int dots = char_count(str, '.'); |
|||
ptr->numbers_ = malloc(sizeof(int) * (dots + 1)); |
|||
if (ptr->numbers_ == 0) |
|||
{ |
|||
oid_destroy(ptr); |
|||
return 0; |
|||
} |
|||
ptr->length_ = dots + 1; |
|||
const char* p = str; |
|||
for (int i = 0; i <= dots && *p;) |
|||
{ |
|||
char* eptr = 0; |
|||
int num = strtol(p, &eptr, 10); |
|||
if (*eptr != 0 && *eptr != '.') |
|||
{ |
|||
// TODO: check for overflow/underflow |
|||
oid_destroy(ptr); |
|||
return 0; |
|||
} |
|||
ptr->numbers_[i++] = num; |
|||
p = eptr; |
|||
if (*p) |
|||
++p; |
|||
} |
|||
return ptr; |
|||
} |
|||
// compare two OIDs |
|||
int oid_compare(const void* p1, const void* p2) |
|||
{ |
|||
const oid* o1 = *(oid* const*)p1; |
|||
const oid* o2 = *(oid* const*)p2; |
|||
int i1 = 0, i2 = 0; |
|||
for (; i1 < o1->length_ && i2 < o2->length_; ++i1, ++i2) |
|||
{ |
|||
if (o1->numbers_[i1] < o2->numbers_[i2]) |
|||
return -1; |
|||
if (o1->numbers_[i1] > o2->numbers_[i2]) |
|||
return 1; |
|||
} |
|||
if (o1->length_ < o2->length_) |
|||
return -1; |
|||
if (o1->length_ > o2->length_) |
|||
return 1; |
|||
return 0; |
|||
} |
|||
int main() |
|||
{ |
|||
const char* input[] = { |
|||
"1.3.6.1.4.1.11.2.17.19.3.4.0.10", |
|||
"1.3.6.1.4.1.11.2.17.5.2.0.79", |
|||
"1.3.6.1.4.1.11.2.17.19.3.4.0.4", |
|||
"1.3.6.1.4.1.11150.3.4.0.1", |
|||
"1.3.6.1.4.1.11.2.17.19.3.4.0.1", |
|||
"1.3.6.1.4.1.11150.3.4.0" |
|||
}; |
|||
const int len = sizeof(input)/sizeof(input[0]); |
|||
oid* oids[len] = { 0 }; |
|||
int i; |
|||
for (i = 0; i < len; ++i) |
|||
{ |
|||
oids[i] = oid_create(input[i]); |
|||
if (oids[i] == 0) |
|||
{ |
|||
fprintf(stderr, "Out of memory\n"); |
|||
goto cleanup; |
|||
} |
|||
} |
|||
qsort(oids, len, sizeof(oid*), oid_compare); |
|||
for (i = 0; i < len; ++i) |
|||
puts(oids[i]->str_); |
|||
cleanup: |
|||
for (i = 0; i < len; ++i) |
|||
oid_destroy(oids[i]); |
|||
return 0; |
|||
}</lang> |
|||
{{out}} |
|||
<pre> |
|||
1.3.6.1.4.1.11.2.17.5.2.0.79 |
|||
1.3.6.1.4.1.11.2.17.19.3.4.0.1 |
1.3.6.1.4.1.11.2.17.19.3.4.0.1 |
||
1.3.6.1.4.1.11.2.17.19.3.4.0.4 |
1.3.6.1.4.1.11.2.17.19.3.4.0.4 |