受到@StoryTeller 的启发,我尝试使用他的方法。
我只考虑给定的 3 个数组来构建代码:
const uint8_t arr_1[] = {1, 4, 53 , 209};
const uint8_t arr_2[] = {54, 56, 90, 100};
const uint8_t arr_3[] = {6, 7, 8, 9, 10};
因为我不知道数据是如何给出的。这个想法是正确的,我假设数组总是排序的。如果将来不是这种情况,那么您可以事先使用qsort 对数组进行排序,平均运行时间为 O(nlogn)。
在下面的代码中,我使用了:
-
stdlib.h提供的内置bsearch函数,省去你自己写的麻烦。使用这个二分搜索工具仍然允许 O(logn) 搜索时间,这比线性搜索消耗的 O(n) 时间要好得多。
-
结构数组设置,收集有关每个数组的特定信息,例如检查[min, max] 范围,并跳过与搜索键值不在同一范围内的数组
设置:
typedef struct {
const uint8_t *p_arr;
uint8_t currsize; * size of each array */
uint8_t max; /* Ranges */
uint8_t min;
} array_t;
typedef struct {
array_t *A; /* pointer to array information */
uint8_t numarrays; /* just a buddy vairable to keep track of n arrays */
} data_t;
-
对malloc 和free 的必要调用,为堆上的指针变量分配和释放空间。
这是我想出的:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define INITSIZE 3
typedef struct {
const uint8_t *p_arr;
uint8_t currsize;
uint8_t max;
uint8_t min;
} array_t;
typedef struct {
array_t *A;
uint8_t numarrays;
} data_t;
data_t *initialize_meta_data(void);
int check_arrays(const uint8_t arr[], const size_t n, uint8_t *key);
void set_arrays(data_t *data, const uint8_t arr[], const size_t n, int index);
void search_arrays(data_t *data, uint8_t key);
int cmpfunc(const void *a, const void *b);
int
main(void) {
const uint8_t arr_1[] = {1, 4, 53 , 209};
const uint8_t arr_2[] = {54, 56, 90, 100};
const uint8_t arr_3[] = {6, 7, 8, 9, 10};
const size_t size1 = sizeof(arr_1)/sizeof(*arr_1);
const size_t size2 = sizeof(arr_2)/sizeof(*arr_2);
const size_t size3 = sizeof(arr_3)/sizeof(*arr_3);
data_t *data = initialize_meta_data();
data->A = malloc(data->numarrays * sizeof(*(data->A)));
set_arrays(data, arr_1, size1, 0);
set_arrays(data, arr_2, size2, 1);
set_arrays(data, arr_3, size3, 2);
/* Number to search for */
uint8_t key = 10;
search_arrays(data, key);
free(data->A);
free(data);
return 0;
}
void
search_arrays(data_t *data, uint8_t key) {
int i;
for (i = 0; i < data->numarrays; i++) {
if ((key <= data->A[i].max) && (key >= data->A[i].min)) {
if (check_arrays(data->A[i].p_arr, data->A[i].currsize, &key)) {
printf("%d found in array number: %d\n", key, i+1);
}
} else {
printf("array number: %d skipped\n", i+1);
}
}
}
void
set_arrays(data_t *data, const uint8_t arr[], const size_t n, int index) {
data->A[index].p_arr = arr;
data->A[index].currsize = n;
data->A[index].max = data->A[index].p_arr[data->A[index].currsize-1];
data->A[index].min = data->A[index].p_arr[0];
}
data_t
*initialize_meta_data(void) {
data_t *data = malloc(sizeof(*data));
data->A = NULL;
data->numarrays = INITSIZE;
return data;
}
int
check_arrays(const uint8_t arr[], const size_t n, uint8_t *key) {
uint8_t *item;
item = bsearch(key, arr, n, sizeof(*arr), cmpfunc);
if (item != NULL) {
return 1;
}
return 0;
}
int
cmpfunc(const void *a, const void *b) {
return (*(uint8_t*)a > *(uint8_t*)b) - (*(uint8_t*)a < *(uint8_t*)b);
}
总体而言,此代码可以进行大量优化,您可能会为您的项目使用非常不同的方法,但想法会相似。
希望对你有所帮助:)