https://troydhanson.github.io/uthash/userguide.html
HASH_ADD用法(结构体作为key):
// HASH_ADD的key类型是结构体,参数共5个
// HASH_ADD 参数:handle, hash_table头指针, key名(在hash_table中定义的key名), sizeof(key结构体类型名), 待插入的hash_table指针)
HASH_ADD(hh, records, key, sizeof(record_key_t), r);
// 注意如果要用函数封装HASH_ADD类函数,头指针形参必须是二级指针!
// HASH_FIND参数也是5个:handle名,hash_table头指针, &key(注意是取地址),sizeof(key结构体类型),结果返回指针temp);
HASH_FIND(hh, records, &l.key, sizeof(record_key_t), p);
snippet ihash "int hash table"
typedef struct {
int key;
int val;
UT_hash_handle hh;
} ${1:HashTable};
// HASH_ADD类函数,要传递哈希对象指针,头指针形参必须用二级指针!
int InsertIntToHash(${1:HashTable} **head, int k, int val)
{
$1 *temp = NULL;
HASH_FIND_INT(*head, &k, temp); // find函数,key需要引用传递
if (temp == NULL) {
temp = ($1 *)malloc(sizeof($1));
temp->key = k;
temp->val = val;
HASH_ADD_INT(*head, key, temp); // add函数,key只是结构体成员名,并非实参
} else {
temp->val = val;
}
}
endsnippet
snippet atohash "insert array to hash"
int InsertArrayToHash(${1:HashTable} **head, int a[], int size)
{
$1 *temp = NULL;
for (int i = 0; i < size; ++i) {
HASH_FIND_INT(*head, &a[i], temp); // find函数,key需要引用传递
if (temp == NULL) {
temp = ($1 *)malloc(sizeof($1));
temp->key = a[i];
temp->val = 1;
HASH_ADD_INT(*head, key, temp); // add函数,key只是结构体成员名,并非实参
} else {
temp->val += 1;
}
}
}
endsnippet
snippet shash "string hash table"
#define STR_LEN 256
typedef struct {
char key[STR_LEN];
int val;
UT_hash_handle hh;
} ${1:HashTable};
int InsertStrToHash($1 **head, char *inKey, int val)
{
$1 *temp = NULL;
HASH_FIND_STR(*head, inKey, temp); // find函数,key需要引用传递,但字符串例外
if (temp == NULL) {
temp = malloc(sizeof($1));
if (strcpy_s(temp->key, STR_LEN, inKey) != 0) {
return -1;
};
temp->val = val;
HASH_ADD_STR(*head, key, temp); // add函数,key 只是结构体成员名,并非实参
} else {
it->val = val;
}
}
endsnippet
snippet strhash "struct hash table"
typedef struct {
int a;
int b;
int c;
} Key_Struct;
typedef struct {
Key_Struct key;
int val;
UT_hash_handle hh;
} ${1:HashTable};
int InsertStructToHash(${1:HashTable} **head, Key_Struct key, int val)
{
$1 *temp = NULL;
// HASH_FIND_INT(*head, &i, temp);
// HASH_FIND参数共5个: handle名, hash_table头指针, &key结构体(注意是取地址),sizeof(key结构体类型),结果返回指针temp);
HASH_FIND(hh, *head, &key, sizeof(Key_Struct), temp);
if (temp == NULL) {
temp = ($1 *)malloc(sizeof($1));
// temp->key = i;
// temp->val = val;
temp->key = key;
temp->val = val;
// HASH_ADD(*head, key, temp);
// HASH_ADD的key类型是结构体,参数共5个
// HASH_ADD 参数:handle类型名, hash_table头指针, key名(在hash_table中定义的key名), sizeof(key结构体类型名), 待插入的hash_table指针)
HASH_ADD(hh, *head, key, sizeof(Key_Struct), temp);
} else {
temp->val = val;
}
}
endsnippet
snippet delhash "Insert int to hash"
void DelAllHash(${1:HashTable} **head)
{
$1 *current_user, *tmp;
HASH_ITER(hh, *head, current_user, tmp) {
HASH_DEL(*head, current_user); /* delete; users advances to next */
free(current_user); /* optional- if you want to free */
}
}
endsnippet
snippet phash "print hash"
void PrintHash(${1:HashTable} *head) {
$1 *s = NULL;
for (s = head; s != NULL; s = s->hh.next) {
printf("user key %d: val %d\n", s->key, s->val);
}
}
endsnippet
snippet ARRAY_SIZE "Insert ARRAY_SIZE"
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
endsnippet
snippet fmax "Insert max function"
int Max(int a, int b)
{
return a > b ? a : b;
}
endsnippet
snippet parray "Insert PrintArray function"
void PrintArray(int *a, int size)
{
for (int i = 0; i < size; ++i) {
printf("%d ", a[i]);
}
}
endsnippet
snippet hsort "Insert hash sort function"
int NameSort(HashTable *a, HashTable *b) {
return strcmp(a->name, b->name);
}
int IdSort(HashTable *a, HashTable *b) {
return (a->id - b->id);
}
void SortByname() {
HASH_SORT(head, NameSort);
}
void SortByid() {
HASH_SORT(head, IdSort);
}
endsnippet
snippet lower_bound "lower_bound"
// 查找大于或等于t的最小地址
int lower_bound_(int a[], int size, int target)
{
if (a[size - 1] < target) {
return size; // 不存在,返回末尾下一个元素
}
int l = 0;
int r = size - 1;
int mid = 0;
// 结束条件: 左边界小于右边界
while (l < r) {
mid = l + (r - l) / 2; // 中点 = (l+r)/2,如果长度(l-r+1)是奇数,则mid一定是中点;如果长度是偶数,则mid为中点左边元素
if (a[mid] < target) {
l = mid + 1; // 如果中点元素小于目标,说明目标值位于右侧,左坐标可以改为中点坐标+1
} else {
r = mid; // 如果中点元素大于或等于目标,说明目标值位于中点左侧(包括中点),把右坐标改为中点位置
}
}
return l;
}
endsnippet
snippet upper_bound "upper_bound"
// 查找大于t的最小地址
int upper_bound_(int a[], int size, int target)
{
if (a[size - 1] <= target) {
return size; // 不存在,返回末尾下一个元素
}
int l = 0;
int r = size - 1;
int mid;
while (l < r) {
mid = l + (r - l) / 2; // 中点 = (l+r)/2
if (a[mid] <= target) {
l = mid + 1; // 如果中点元素小于或等于目标值,说明目标值在右侧,左坐标移动到中点坐标+1
} else {
r = mid; // 如果中点元素小于目标值,说明目标值在左侧(包括中点),右坐标左移到中点位置
}
}
return l;
}
endsnippet
snippet binary_search "binary_search"
int binary_search(int a[], int size, int target)
{
if (a[0] > target || a[size - 1] < target) {
return -1;
}
int l = 0, r = size - 1, mid = 0; // 如果 r 起始值为n,则截止条件为l < r
// 结束条件: 左边界小于或等于右边界
while (l <= r) {
mid = l + (r - l) / 2; // 防止整数溢出
if (a[mid] == target) {
return mid; // 如果中点元素等于目标,说明中点坐标为所求,返回坐标
} else if (a[mid] < target) {
l = mid + 1; // 如果中点元素小于目标,说明目标值位于中点右侧,左坐标可以改为中点坐标+1
} else {
r = mid - 1; // 如果中点元素大于目标,说明目标值位于中点左侧,把右坐标改为中点坐标-1
}
}
return -1; // 未找到
}
endsnippet
snippet strtol "strtol"
int main(void)
{
const char *str = "10 200000000000000000000000000000 30 -40 junk";
const char *start = str;
char *stop = NULL;
// 起始指针,终止指针,进制
long i = strtol(start, &stop, 10);
while (start != stop)
{
char *message = strerror(errno);
if (message != NULL) {
printf("%s\n\n", message);
errno = 0;
}
start = stop;
i = strtol(start, &stop, 10);
}
}
// 另一种用法
int ParseData(char *str, int array[])
{
if (str == NULL) {
return 0;
}
char *start = NULL;
char *stop = NULL;
start = str;
int count = 0;
while (1) {
int num = strtol(start, &stop, 10);
array[count++] = num;
if (stop[0] == '\0') {
start = NULL;
stop = NULL;
break;
}
start = stop + 1;
}
return count;
}
endsnippet
snippet strtok "strtok"
int main(int argc, char *argv[])
{
char str[] = "1,2,3,4,5";
const char *sep = ",";
char *pStr = NULL;
pStr = strtok(str, sep);
while (pStr != NULL) {
printf("%c\n", pStr[0]);
/* printf("%s\n", pStr); */
pStr = strtok(NULL, sep);
}
char str2[] = "1,2,3,4,5";
char *delim = ",";
char *context = NULL;
char *pStr2 = NULL;
pStr2 = strtok_s(str2, delim, &context);
while (pStr2 != NULL) {
printf("%c\n", pStr2[0]);
pStr2 = strtok_s(NULL, delim, &context);
}
return 0;
}
endsnippet
snippet qsort "qsort"
int comp(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}
qsort(array, n, sizeof(array[0]), comp);
/*
base 第一个元素的指针
nitems 数组元素个数
size 数组元素大小
compar 比较函数指针
*/
void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void*, const void*));
endsnippet
snippet include "include"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <securec.h>
#include <ctype.h>
#include <stdbool.h>
#include <errno.h>
#include "uthash.h"
endsnippet
#include <stdlib.h>
#include <stdio.h>
#include "uthash.h"
typedef struct {
char a;
int b;
} record_key_t;
typedef struct {
record_key_t key;
/* ... other data ... */
UT_hash_handle hh;
} record_t;
int main(int argc, char *argv[]) {
record_t l, *p, *r, *tmp, *records = NULL;
r = (record_t *)malloc(sizeof *r);
memset(r, 0, sizeof *r);
r->key.a = 'a';
r->key.b = 1;
// HASH_ADD的key类型是结构体,参数共5个
// HASH_ADD 参数:handle, hash_table头指针, key名(在hash_table中定义的key名), sizeof(key结构体类型名), 待插入的hash_table指针)
HASH_ADD(hh, records, key, sizeof(record_key_t), r);
memset(&l, 0, sizeof(record_t));
l.key.a = 'a';
l.key.b = 1;
// HASH_FIND参数也是5个:handle名,hash_table头指针, &key(注意是取地址),sizeof(key结构体类型),结果返回指针temp);
HASH_FIND(hh, records, &l.key, sizeof(record_key_t), p);
if (p) printf("found %c %d\n", p->key.a, p->key.b);
HASH_ITER(hh, records, p, tmp) {
HASH_DEL(records, p);
free(p);
}
return 0;
}