我不确定数组中元素的类型是什么,但我们假设它是 C 可以“本机”比较的某种类型。然后概念上简单的解决方案是对数组进行排序,并且打印它跳过重复项。排序将确保重复项相邻。这种方法在大多数情况下都会表现良好。
首先,让我们设置一些特定于元素类型的辅助函数。如果您只想处理 char 类型,则可以删除 assign 函数,但无论如何编译器都会内联它。
#include <stdlib.h>
#include <stdio.h>
// You can adapt the element type per your requirements
typedef char ElementType;
// This function assigns the source value to the destination:
// it does what *dst = *src would do.
static inline void assign(void *dst, const void *src)
{
*(ElementType*)dst = *(const ElementType*)src;
}
// This is the "spaceship" comparison operator (<=> in C++) that
// merges less-than, equal, and more-than comparisons into one.
int compare(const void *l, const void *r)
{
const ElementType *L = l;
const ElementType *R = r;
if (*L < *R) return -1;
if (*L > *R) return 1;
return 0;
}
void print_element(const ElementType *el) { printf("%c", *el); }
由于我们计划对数组进行排序,我们需要先复制它——毕竟,数组的“打印机”不应该修改它。这样的修改在小程序中是可以的,但只是一个坏习惯,因为如果你查看函数的名称,如print_unique,没有任何迹象表明它会修改它应该打印的数据:这不是打印通常的行为.这会出乎意料,而且很容易出错。
如果可以修改源数组,则可以跳过复制操作:它的元素需要是非常量的,并且需要将 print_unique 函数名称更改为 sort_and_print_unique 之类的名称。
ElementType *copy_array(const ElementType *src, const int count)
{
ElementType *copy = malloc(sizeof(ElementType) * count);
if (!copy) abort;
for (int i = 0; i < count; ++i)
assign(copy + i, src + i);
return copy;
}
现在是独特的元素打印机,并使用您提供的数据进行测试:
void print_unique(const ElementType *data, int const count)
{
ElementType *copy = copy_array(data, count);
qsort(copy, count, sizeof(ElementType), compare);
printf("[");
for (int i = 0; i < count; ++i) {
if (i == 0 || compare(copy+i, copy+i-1) != 0) {
if (i != 0) printf(" ");
print_element(copy+i);
}
}
printf("]\n");
}
int main() {
const char array[] = "abcdaabdcc";
print_unique(array, sizeof(array)/sizeof(*array) - 1);
}
输出:[a b c d]
我上面提到的替代的修改实现是:
void sort_and_print_unique(ElementType *data, int const count)
{
qsort(data, count, sizeof(ElementType), compare);
printf("[");
for (int i = 0; i < count; ++i) {
if (i == 0 || compare(data+i, data+i-1) != 0) {
if (i != 0) printf(" ");
print_element(data+i);
}
}
printf("]\n");
}
int main() {
char array[] = "abcdaabdcc"; // note absence of const!
sort_and_print_unique(array, sizeof(array)/sizeof(*array) - 1);
}