Skip to content

Commit

Permalink
str_unique_range() function added.
Browse files Browse the repository at this point in the history
  • Loading branch information
maxim2266 committed Apr 16, 2020
1 parent f6fbf6c commit 10cde3c
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 3 deletions.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,11 +282,18 @@ of typically used comparison functions is also provided:
Binary search for the given key. The input array must be sorted using `str_order_asc`.
Returns a pointer to the string matching the key, or NULL.
`size_t str_partition_range(bool (*pred)(const str), const str* const array, const size_t count)`<br>
`size_t str_partition_range(bool (*pred)(const str), str* const array, const size_t count)`<br>
Reorders the string objects in the given range in such a way that all elements for which
the predicate `pred` returns "true" precede the elements for which predicate `pred`
returns "false". Returns the number of preceding objects.
`size_t str_unique_range(str* const array, const size_t count)`<br>
Reorders the string objects in the given range in such a way that there are two partitions:
one where each object is unique within the input range, and another partition with all the
remaining objects. The unique partition is stored at the beginning of the array, and is
sorted in ascending order, followed by the partition with remaining objects.
Returns the number of unique objects.
#### Memory Management
`void str_free(const str s)`<br>
Expand Down
25 changes: 23 additions & 2 deletions str.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ int str_order_desc_ci(const void* const s1, const void* const s2)
// sorting
void str_sort_range(const str_cmp_func cmp, str* const array, const size_t count)
{
if(array && cmp && count > 1)
if(array && count > 1)
qsort(array, count, sizeof(array[0]), cmp);
}

Expand Down Expand Up @@ -452,4 +452,25 @@ size_t str_partition_range(bool (*pred)(const str), str* const array, const size
str_swap(p++, s);

return p - array;
}
}

// unique partitioning
size_t str_unique_range(str* const array, const size_t count)
{
if(!array || count == 0)
return 0;

if(count == 1)
return 1;

str_sort_range(str_order_asc, array, count);

const str* const end = array + count;
str* p = array;

for(str* s = array + 1; s < end; ++s)
if(!str_eq(*p, *s) && (++p < s))
str_swap(p, s);

return p + 1 - array;
}
3 changes: 3 additions & 0 deletions str.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,9 @@ const str* str_search_range(const str key, const str* const array, const size_t
// partitioning
size_t str_partition_range(bool (*pred)(const str), str* const array, const size_t count);

// unique partitioning
size_t str_unique_range(str* const array, const size_t count);

#ifdef __cplusplus
}
#endif
30 changes: 30 additions & 0 deletions str_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -477,9 +477,13 @@ void test_partition_range(void)
{
str src[] = { str_lit("aaa"), str_lit("a"), str_lit("aaaa"), str_lit("z") };

assert(str_partition_range(part_pred, src, 1) == 0);

assert(str_partition_range(part_pred, src, sizeof(src)/sizeof(src[0])) == 2);
assert(str_eq(src[0], str_lit("a")));
assert(str_eq(src[1], str_lit("z")));
assert(str_partition_range(part_pred, src, 1) == 1);


src[0] = str_lit("?");
src[2] = str_lit("*");
Expand All @@ -496,6 +500,31 @@ void test_partition_range(void)
passed;
}

static
void test_unique_range(void)
{
str src[] = {
str_lit("zzz"),
str_lit("aaa"),
str_lit("zzz"),
str_lit("bbb"),
str_lit("aaa"),
str_lit("ccc"),
str_lit("ccc"),
str_lit("aaa"),
str_lit("ccc"),
str_lit("zzz")
};

assert(str_unique_range(src, sizeof(src)/sizeof(src[0])) == 4);
assert(str_eq(src[0], str_lit("aaa")));
assert(str_eq(src[1], str_lit("bbb")));
assert(str_eq(src[2], str_lit("ccc")));
assert(str_eq(src[3], str_lit("zzz")));

passed;
}

int main(void)
{
// tests
Expand All @@ -522,6 +551,7 @@ int main(void)
test_str_join_to_fd();
test_str_join_to_stream();
test_partition_range();
test_unique_range();

return puts("OK.") < 0;
}

0 comments on commit 10cde3c

Please sign in to comment.