c语言hash使用模板

typedef struct{
    int key;
    int val;
    UT_hash_handle hh;
}HashItem;

HashItem *hashFindItem(HashItem **obj,int key){
    HashItem *pEntry = NULL;
    HASH_FIND_INT(*obj,&key,pEntry);
    return pEntry;
}

bool hashAddItem(HashItem **obj, int key, int val) {
    if (hashFindItem(obj, key)) {
        return false;
    }
    HashItem *pEntry = (HashItem *)malloc(sizeof(HashItem));
    pEntry->key = key;
    pEntry->val = val;
    HASH_ADD_INT(*obj, key, pEntry);
    return true;
}

bool hashSetItem(HashItem **obj, int key, int val) {
    HashItem *pEntry = hashFindItem(obj, key);
    if (!pEntry) {
        hashAddItem(obj, key, val);
    } else {
        pEntry->val = val;
    }
    return true;
}

int hashGetItem(HashItem **obj, int key, int defaultVal) {
    HashItem *pEntry = hashFindItem(obj, key);
    if (!pEntry) {
        return defaultVal;
    }
    return pEntry->val;
}

void hashFree(HashItem **obj) {
    HashItem *curr = NULL, *tmp = NULL;
    HASH_ITER(hh, *obj, curr, tmp) {
        HASH_DEL(*obj, curr);  
        free(curr);             
    }
}

话不多说,直接上code了,大致说明一下如何使用

我们实战中用到最多的就是hashSetItem  和hashGetItem,  写表,读表这两个操作

hashSetltm(&counts,key,val)     hashGetltm(&counts,key,val)

好了,已经介绍完毕,那我们就来做到题吧。

 思路:

①数组内的数字从1-n,而且还不重复,那说明k只有一个

②中位数:奇数为中间,偶数中间偏左。说明奇数时k为中间值,偶数时k为中间偏左。

③转化思想,大于k的数为1,小于k的数为-1,等于k的数为0

④ nums[idx] = k;   k1 < idx < k2    如果k2的前缀和 -  k1的前缀和为  1/0,那他就是一个满足条件的子数组

show show code !!

typedef struct{
    int key;
    int val;
    UT_hash_handle hh;
}HashItem;

HashItem *hashFindItem(HashItem **obj,int key){
    HashItem *pEntry = NULL;
    HASH_FIND_INT(*obj,&key,pEntry);
    return pEntry;
}

bool hashAddItem(HashItem **obj, int key, int val) {
    if (hashFindItem(obj, key)) {
        return false;
    }
    HashItem *pEntry = (HashItem *)malloc(sizeof(HashItem));
    pEntry->key = key;
    pEntry->val = val;
    HASH_ADD_INT(*obj, key, pEntry);
    return true;
}

bool hashSetItem(HashItem **obj, int key, int val) {
    HashItem *pEntry = hashFindItem(obj, key);
    if (!pEntry) {
        hashAddItem(obj, key, val);
    } else {
        pEntry->val = val;
    }
    return true;
}

int hashGetItem(HashItem **obj, int key, int defaultVal) {
    HashItem *pEntry = hashFindItem(obj, key);
    if (!pEntry) {
        return defaultVal;
    }
    return pEntry->val;
}

void hashFree(HashItem **obj) {
    HashItem *curr = NULL, *tmp = NULL;
    HASH_ITER(hh, *obj, curr, tmp) {
        HASH_DEL(*obj, curr);  
        free(curr);             
    }
}

int sign(int num)
{
    if(num == 0)
    {
        return 0;
    }
    return num>0?1:-1;
}
int countSubarrays(int* nums, int numsSize, int k){
    HashItem* counts = NULL;
    hashSetItem(&counts,0,1);
    int sum = 0;
    int ans = 0;
    int idx;
    for(int i = 0;i<numsSize;i++)
    {
        if(nums[i] == k)
        {
            idx = i;
            break;
        }
    }
    for(int i = 0;i<numsSize;i++)
    {
        sum += sign(nums[i] - k);
        if(i < idx)
        {
            hashSetItem(&counts,sum,hashGetItem(&counts,sum,0)+1);
        }
        else
        {
            int ak0 = hashGetItem(&counts,sum,0);
            int ak1 = hashGetItem(&counts,sum-1,0);
            ans += ak0 + ak1;
        }
    }
    return ans;

}

over boy!

新增一條,遍歷hash表


int cmp(const void* a, const void* b){
    return *(int*)a > *(int*)b;
}
typedef struct{
    int key;
    int val;
    UT_hash_handle hh;
}HashItem;
 
HashItem *hashFindItem(HashItem **obj,int key){
    HashItem *pEntry = NULL;
    HASH_FIND_INT(*obj,&key,pEntry);
    return pEntry;
}
 
bool hashAddItem(HashItem **obj, int key, int val) {
    if (hashFindItem(obj, key)) {
        return false;
    }
    HashItem *pEntry = (HashItem *)malloc(sizeof(HashItem));
    pEntry->key = key;
    pEntry->val = val;
    HASH_ADD_INT(*obj, key, pEntry);
    return true;
}
 
bool hashSetItem(HashItem **obj, int key, int val) {
    HashItem *pEntry = hashFindItem(obj, key);
    if (!pEntry) {
        hashAddItem(obj, key, val);
    } else {
        pEntry->val = val;
    }
    return true;
}
 
int hashGetItem(HashItem **obj, int key, int defaultVal) {
    HashItem *pEntry = hashFindItem(obj, key);
    if (!pEntry) {
        return defaultVal;
    }
    return pEntry->val;
}
 
void hashFree(HashItem **obj) {
    HashItem *curr = NULL, *tmp = NULL;
    HASH_ITER(hh, *obj, curr, tmp) {
        HASH_DEL(*obj, curr);  
        free(curr);             
    }
}
int tupleSameProduct(int* nums, int numsSize){
    HashItem* counts = NULL;
    for(int i = 0;i<numsSize;i++){
        for(int j = i+1;j<numsSize;j++){
            hashSetItem(&counts,nums[i]*nums[j],hashGetItem(&counts,nums[i]*nums[j],0)+1);
        }
    }
    int ans = 0 ;
    for (HashItem *pEntry = counts; pEntry; pEntry = pEntry->hh.next) {
        int val = pEntry->val;
        ans += val * (val - 1) * 4;
    }
    return ans;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值