1,有序数组中二分查找(相等时最左或最右)
int binarySearchValue(int a[], int n, int value, bool is_left)
{
if (!a || n <= 0)
return -1;
int result = -1;
int left = 0, right = n - 1;
while (left <= right) {
int mid = left + ((right - left) >> 2);
if (value < a[mid])
right = mid - 1;
else if (value > a[mid])
left = mid + 1;
else {
result = mid;
if (is_left)
right = mid - 1;
else
left = mid + 1;
}
}
return result;
}
2,字符串的动态增加并排序
思想:1,扩容:利用动态数组思想,当字符串数组array_str元素满了时,通过分配拷贝释放办法扩容
2,排序:开辟一个字符串数组的下标的排序数组array_pos,利用二分查找,找到新元素下标该插入位置,然后将新元素下标插入到下标数组。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char bool;
typedef struct buffer {
char *str;
int size;
int used;
}buffer;
typedef struct array {
buffer **bptr;
int size;
int used;
}array;
typedef struct num_array {
int *nptr;
int size;
int used;
}num_array;
#define PICECE_SIZE 64
buffer *buffer_init(void)
{
buffer *b;
if (!(b = calloc(1, sizeof(buffer)))) {
fprintf(stderr, "%s.%d:malloc fail\n", __FILE__, __LINE__);
exit(1);
}
return b;
}
void buffer_struct_free(buffer *b);
void buffer_exit(buffer *b)
{
if (b) {
buffer_struct_free(b);
b = NULL;
}
return ;
}
buffer *buffer_copy_string(buffer *b, char *str)
{
if (!b || !str)
return b;
if (b->size < strlen(str) + 1) {
b->size = strlen(str) + 1 + (PICECE_SIZE - (strlen(str) + 1) % PICECE_SIZE);
if (b->str) {
free(b->str);
b->str = NULL;
}
if (!(b->str = calloc(b->size, sizeof(char)))) {
fprintf(stderr, "%s.%d:calloc fail\n", __FILE__,__LINE__);
exit(1);
}
}
memcpy(b->str, str, strlen(str));
b->str[strlen(str)] = '\0';
b->used = strlen(str) + 1;
}
int buffer_reset(buffer *b)
{
if (!b)
return -1;
b->used = 0;
return 0;
}
void buffer_context_free(buffer *b)
{
free(b->str);
b->str = NULL;
b->size = 0;
b->used = 0;
return ;
}
void buffer_struct_free(buffer *b)
{
free(b);
return ;
}
void buffer_free(buffer *b)
{
if (!b)
return ;
buffer_context_free(b);
buffer_struct_free(b);
return ;
}
int buffer_copy(buffer *dst, const buffer *src)
{
if (!src || !dst)
return -1;
buffer_reset(dst);
if (src->used > dst->size) {
buffer_context_free(dst);
dst->size = src->used + (PICECE_SIZE - src->used % PICECE_SIZE);
if (!(dst->str = calloc(dst->size, sizeof(char)))) {
fprintf(stderr, "%s.%d:calloc fail\n", __FILE__, __LINE__);
exit(1);
}
}
memcpy(dst->str, src->str, src->used);
dst->used = src->used;
}
int buffer_compare(buffer *b1, buffer *b2)
{
if (!b1)
return -1;
if (!b2)
return 1;
int len = b1->used > b2->used ? b2->used : b1->used;
int i;
for (i = 0; i < len; i++) {
if (b1->str[i] != b2->str[i])
return b1->str[i] - b2->str[i];
else
continue ;
}
return b1->used - b2->used;
}
array *array_init(void)
{
array *a;
if (!(a = calloc(1,sizeof(array))))
exit(1);
return a;
}
bool array_is_full(array *a)
{
return (a->used == a->size);
}
void array_contxt_free(array *a)
{
if (!a)
return ;
int i;
for (i = 0; i < a->used; i++)
buffer_free(a->bptr[i]);
free(a->bptr);
return ;
}
void array_struct_free(array *a)
{
if (!a)
return ;
free(a);
a = NULL;
return ;
}
void array_free(array *a)
{
#if 0
if (!a)
return ;
int i;
for (i = 0; i < a->used; i++)
buffer_free(a->bptr[i]);
free(a->bptr);
a->bptr = NULL;
a->used = 0;
a->size = 0;
return ;
#else
array_contxt_free(a);
array_struct_free(a);
return ;
#endif
}
void array_exit(array *a)
{
#if 0
if (a) {
if (a->size) {
array_free(a);
}
free(a);
a = NULL;
}
#else
array_struct_free(a);
#endif
return ;
}
num_array *num_array_init(void)
{
num_array *n;
if (!(n = calloc(1,sizeof(num_array))))
exit(1);
return n;
}
void num_array_free(num_array *n)
{
if (!n)
return ;
free(n->nptr);
n->nptr = NULL;
n->used = 0;
n->size = 0;
free(n);
return ;
}
void num_array_exit(num_array *n)
{
if (n) {
free(n);
n = NULL;
}
return ;
}
#if 0
void realloc_array(array *a)
{
buffer *b;
int used = a->used;
int size = a->used + (PICECE_SIZE - a->used % PICECE_SIZE);
if (!(b = calloc(size, sizeof(buffer)))) {
fprintf(stderr, "%s.%d:calloc fail\n", __FILE__, __LINE__);
exit(1);
}
int i;
for (i = 0; i < used; i++) {
buffer_copy(&b[i], &a->bptr[i]);
}
array_free(a);
a->bptr = b;
a->used = used;
a->size = size;
return ;
}
#else
void enlarge_array(array *a)
{
a->size = a->used + (PICECE_SIZE - a->used % PICECE_SIZE);
a->bptr = realloc(a->bptr, sizeof(*a->bptr) * a->size);
}
#endif
int get_insert_pos(array *a, num_array *n, int left, int right, buffer *target)
{
if (!a || !n)
return -2;
if (!left && right == -1 )
return -1;
while (left <= right) {
int mid = left + ((right - left) >> 1);
int ret = 0;
if ((ret = buffer_compare(target, a->bptr[n->nptr[mid]]) )>= 0)
left = mid + 1;
else if (ret < 0)
right = mid - 1;
}
return left;
}
void enlarge_num_array(num_array *n);
void soted_array_dupinclude_insert(array *a, num_array *n, int index)
{
if (index + 1 > a->size) {
fprintf(stderr, "%s.%d:bug\n", __FILE__, __LINE__);
exit(1);
}
if (n->used + 1 > n->size) {
#if 0
int size = n->used + 1 + (PICECE_SIZE - (n->used + 1) % PICECE_SIZE);
int used = n->used;
int *tmp = NULL;
if (!(tmp = calloc(size, sizeof(int)))) {
fprintf(stderr, "%s.%d:calloc fail\n", __FILE__, __LINE__);
exit(1);
}
int i;
for (i = 0; i < used; i++)
tmp[i] = n->nptr[i];
free(n->nptr);
n->nptr = tmp;
n->used = used;
n->size = size;
#else
enlarge_num_array(n);
#endif
}
int pos = get_insert_pos(a, n, 0, n->used - 1, a->bptr[index]);
if (pos >= 0) {
int i;
for (i = n->used - 1;i >= pos; i--)
n->nptr[i + 1] = n->nptr[i];
n->nptr[pos] = index;
} else if (pos == -1) {
n->nptr[0] = index;
}
n->used++;
return ;
}
void enlarge_num_array(num_array *n)
{
n->size = n->used + (PICECE_SIZE - n->used % PICECE_SIZE);
n->nptr = realloc(n->nptr, sizeof(int) * n->size);
return ;
}
void array_insert(array *a, num_array *n, char *str)
{
if (!a|| !str ||!n)
return ;
//ljg:array which is not alloced is considered as full
if (array_is_full(a)) {
enlarge_array(a);
}
if (!(a->bptr[a->used] = buffer_init()))
exit(1);
buffer_copy_string(a->bptr[a->used], str);
a->used++;
soted_array_dupinclude_insert(a, n, a->used - 1);
return ;
}
int rand_str_generate(char *str, int max_len)
{
if (!str || max_len <= 0)
return -1;
// srand(time(NULL));
int count = 0;
while (count < max_len) {
#if 0
str[count] = rand() % 128;
count++;
if (str[count - 1] == '\0' || str[count - 1] == '\n' || str[count - 1] == '\t' || str[count - 1] == ' ')
break;
#else
int ret = rand() % 56;
if (ret < 10 && ret >= 0)
str[count] = '0' + ret;
else if (ret >= 10 && ret < 36)
str[count] = 'A' + ret - 10;
else
str[count] = 'a' + ret - 36;
count++;
#endif
}
str[count - 1] = '\0';
return 0;
}
void print_sorted_str(array *a, num_array *n)
{
int i;
for (i = 0; i < n->used; i++) {
printf("%s\n", a->bptr[n->nptr[i]]->str);
}
}
int main(void)
{
array *a = array_init();
num_array *n = num_array_init();
char str[64];
int count = 0;
for (count = 0; count < 30; count++) {
rand_str_generate(str, 16);
array_insert(a, n, str);
}
print_sorted_str(a, n);
array_free(a);
num_array_free(n);
return 0;
}
3,命令行参数解析函数getopt()
每调用一次getopt()函数,返回一个选项,如果该选项有参数,则optarg指向该参数
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
int main(int argc, char **argv)
{
int c, count;
while ((c = <span style="color:#ff6666;">getopt(argc, argv, "dtc:")</span>) != -1) {
switch (c) {
case 'd':
printf("date:%s\t", __DATE__);
break;
case 't':
printf("time:%s\t", __TIME__);
break;
case 'c':
count = atoi(optarg);
printf("count_s:%s\t", optarg);
printf("count_n:%d\t", count);
break;
default:
return -1;
}
4,字符串hash函数
unsigned int DEK_hash(char *str)
{
unsigned int hash = 1315423911;
unsigned int ch = 0;
while ((ch = *str++)) {
hash = (hash << 5) ^ (hash >> 27) ^ ch;
str++;
}
return hash;
}
int rand_str_generate(char *str, int max_len)
{
if (!str || max_len <= 0)
return -1;
// srand(time(NULL));
int count = 0;
while (count < max_len) {
str[count] = rand() % 128;
count++;
if (str[count - 1] == '\0')
break;
}
str[count - 1] = '\0';
return 0;
}