代码有点乱 ----先实现 ,聊接基本原理 后续用c++改善一下代码
参考:魔法学院
/*
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
using namespace std;
*/
#include<stdio.h>
#include<malloc.h>
#include<string.h>
struct Pair
{
char* key;
char* value;
};
struct Bucket
{
int count;
Pair *pair;
//Bucket *next;
};
struct Map
{
Bucket* bucket;
int count;
};
typedef Pair pair;
typedef Bucket bucket;
typedef Map map;
Map* initmap(int sum)
{
//Map* map=new Map[sum];
Map* map= (Map*)malloc(sizeof(Map));
if(map ==NULL) return NULL;
map->bucket=(Bucket*)malloc(sizeof(Bucket)*sum);
if (map->bucket == NULL) {
free(map);
map=NULL;
return NULL;
}
map->count=sum;
memset(map->bucket, 0, map->count * sizeof(Bucket));
// I USE FOR LOW I WAS
return map;
}
unsigned int hash(const char* key)
{
unsigned int hash =0;
int c;
//char* c=key; error
while(c=*key++)
{
hash=hash*33 +c;
}
return hash;
// use class return hash/count ;
}
static Pair* get_pair(Bucket *bucket, const char *key)
{
int i,n=0;
Pair* pair;
//unsigned int index= hash(key);
i =bucket->count;
if(i == 0) return NULL;
pair = bucket->pair;
while( n < i )
{
if( (pair->key !=NULL )&&(pair->value !=NULL) )
{
if( 0==strcmp(pair->key,key) )
{
return pair;
}
}
pair++;
n++;
}
return NULL;
}
int sm_get(const Map *map, const char *key, char *out_buf, unsigned int n_out_buf)
{
//bool ret=0;
//char* out=(char*)malloc(sizeof(char)*10);
unsigned int index;
Bucket *bucket;
Pair* pair;
index= hash(key);
index= index% map->count;
//bucket=map->bucket[index]; 2
bucket=&(map->bucket[index]);
pair=get_pair(bucket,key);
//if( pair=NULL) return 0; 3
if(out_buf ==0 && n_out_buf==0) return strlen(pair->value)+1;
if(out_buf ==0 ) return 0;
if(n_out_buf<strlen(pair->value)+1) return 0;
printf("%s\n",pair->value);
strcpy(out_buf,pair->value);
return 1;
}
/*
run:
if( pair=NULL) return 0; 3
Starting program: /home/ct/Desktop/hash
count = 1
======
on
Program received signal SIGSEGV, Segmentation fault.
just because : if( pair=NULL)
oh my god -----------future must write "NULL == pair"
*/
bool sm_exist (Map* map,char* key)
{
int ret=0;
unsigned int index ;
Pair* pair;
Bucket *bucket;
// int i,n=bucket->count;
index = hash(key);
index= index% map->count;
bucket=&(map->bucket[index]);
pair=bucket->pair;
/* for(i=0;i<n;i++)
{
if(0 ==strcmp(pair->key,key) )
return ret=1;
}
*/
if(0 ==strcmp(pair->key,key) )
return ret=1;
return ret;
}
char* sm_alloc(char* str)
{
int l=strlen(str)+1;
char* dest=(char*)malloc(sizeof(char)*l);
strcpy(dest,str);
return dest;
}
bool sm_install(Map* map,char* key,char* value)
{
bool ret =0;
unsigned int index;
Pair* pair,*tem_pair;
Bucket *bucket;
char* new_key,*new_value;
int key_len=strlen(key);
int value_len=strlen(value);
index = hash(key);
index= index% map->count;
bucket=&(map->bucket[index]);
if( (pair=get_pair(bucket,key)) !=NULL)
{
//attention to the priority----
// pair= get_pair(bucket,key))! =NULL hash.cpp:140:9: error: cannot convert ‘bool’ to ‘Pair*’ in assignment
free(pair->value);
pair->value=sm_alloc(value);
return ret=1;
}
new_key=sm_alloc(key);
new_value=sm_alloc(value);
if( bucket->count ==0 )
{
tem_pair=(Pair*)malloc(sizeof(Pair));//1
if(tem_pair==NULL)
{
free(new_key);
free(new_value);
}
bucket->pair=tem_pair;
bucket->count=1;
}else{
tem_pair=(Pair*)realloc( bucket->pair,sizeof(Bucket)*(bucket->count+1) );
if(tem_pair==NULL)
{
free(new_key);
free(new_value);
}
bucket->pair=tem_pair;
bucket->count++;
}
pair=&(bucket->pair[bucket->count-1]);
pair->key=new_key;
pair->value=new_value;
return ret=1;
}
void show(Pair* pair,void* pri)
{
if( pair == NULL)
{
printf("()\n");
}else{
printf("key =%s value=%s \n",pair->key,pair->value);
}
return;
}
int sm_enum(Map* map,void(*f)(Pair* pair,void* data),void* pdata)
{
int i,j,mc,bc;
Bucket* bucket=map->bucket;
Pair* pair;
if(map==NULL) return 0;
mc=map->count;
for(i=0;i<mc;i++)
{
bc=bucket->count;
/*
bc=bucket[i].count;error bacase pair=bucket->pair----> always on the // bucket[0]
bucket->count; bucket++;
*every bucket has count;
*/
pair=bucket->pair;
for(j=0;j<bc;j++)
{
show(pair,pdata);
pair++;
}
bucket++;
}
return 1;
}
int get_count(Map* map)
{
int i,mc,bc,sum=0;
Bucket* bucket=map->bucket;
if(map==NULL) return 0;
mc=map->count;
for(i=0;i<mc;i++)
{
bc=bucket[i].count;
sum=sum+bc;
}
return sum;
}
bool sm_delt(Map* map)
{
bool ret=0;
int bc,mc,i=0,j=0;
Bucket* bucket;
Pair* pair;
mc=map->count;
bucket=map->bucket;
while(i<mc)
{
pair=bucket->pair;
bc=bucket->count;
while(j < bc)
{
// free(pair->key) ;
// free(pair->value);
pair++;
j++;
}
//free(bucket->pair);
bucket++;
i++; // forget i++ result --->free the point twice segment fault
}
free(map->bucket);
free(map);
map=NULL;
return 0;
}
int main()
{
int cc=0;
char out[10];
Map* map=initmap(100);
sm_install(map,"one","my");
sm_install(map,"two","heart");
sm_install(map,"three","will");
sm_install(map,"four","go");
sm_install(map,"five","on");
sm_install(map,"ffffffff3e","6666");
cc=sm_exist(map,"five");
//cc=get_count(map);
printf("count = %d\n",cc);
sm_get(map,"five",out,10);
printf("str = %s\n",out);
printf("shut thanks\n");
sm_enum( map,show,NULL);
sm_delt( map);
return 0;
}