zoukankan      html  css  js  c++  java
  • 字典

    字典在很多高级语言里都有,比如

    1. js的对象结构可以当字典来用
    2. python的字典
    3. go的map
    4. ......................

    但是你们知道字典是怎么实现的吗?本文来实现一个简单的字典。

    python的字典

    先来看python的字典是怎样的

    d = {}
    d["name"]="biningo"
    d["age"] = "19"
    name = d.get("name")
    age = d.get("age")
    

    c语言实现

    参考了Redis的字典结构。字典在redis底层应用非常普遍。因为redis是一个K-V数据库

    这里只是实现了string类型的字典,键值都是string

    用一个Hash Table来存放键值,线性探测法解决冲突【redis是用拉链法】

    dictEntry:存放K-V的结构体

    struct dictEntry{
    	string key;
    	string val; 
    };
    

    dict:字典,里面有一个Hash Table

    //字典 无序 
    struct dict{
    	dictEntry** table; //哈希表数组
    	int size; //哈希表大小
    	int len;  //键值对计数器  
    };
    

    根据string来计算Hash Code

    //计算str的哈希值  参照java hashCode 
    int hash(string s){
    	int h = 0;
    	for(int i=0;i<s.length();i++){
    		h = 31 * h + (s[i] & 0xff);
    	}
    	return h;
    }
    

    创建空字典

    dict* dictCreate(int size){
    	dict* d = (dict*)malloc(sizeof(dict));
    	d->table = (dictEntry**)calloc(size,sizeof(dictEntry*)); //这里要注意了 
    	for(int i=0;i<size;i++)
    		d->table[i] = NULL;
    	d->size = size;//size当作负载因子 
    	d->len=0;
    	return d;	 
    }
    

    Get、Set

    void set(dict* d,string key,string val){
    	if(d->size==d->len){
    		cout<<"哈希表满了"<<endl; 
    		return;
    	}
    	int index = hash(key)%d->size;
    	while(d->table[index]!=NULL){
    		index = (index+1)%d->size;
    	}
    	d->table[index]  = (dictEntry*)malloc(sizeof(dictEntry)); //先开辟空间 
    	d->table[index]->val = val;
    	d->table[index]->key = key;
    	d->len++;
    	return;
    }
    
    string get(dict* d,string key){
    	if(d->len==0){
    		cout<<"哈希表空的"<<endl;
    		return "";
    	}
    	int index = hash(key)%d->size;
    	int c=1;
    	while( c<d->size){
    		if(d->table[index] && d->table[index]->key==key)
    			break;
    		index = (index+1)%d->size;
    		c++;
    	}
    	if(c<d->size){
    		d->len--;
    		return d->table[index]->val;	
    	}
    	else{
    		cout<<"找不到元素"<<endl;
    		return "";
    	} 
    }
    

    删除键值

    //根据键查找哈希表的索引 
    int getIndex(dict* d,string key){
    	if(d->len==0){
    		cout<<"哈希表空的"<<endl;
    		return -1;
    	}
    	int index = hash(key)%d->size;
    	int c=1;
    	while( c<d->size && d->table[index]->key!=key){
    		index = (index+1)%d->size;
    		c++;
    	}
    	if(c<d->size)
    		return index;
    	else{
    		cout<<"找不到元素"<<endl;
    		return -1;
    	} 
    }
    
    //根据键删除键值对 
    void DeleteByKey(dict* d,string key){
    	 int i = getIndex(d,key);
    	 if(i>=0){
     		d->table[i] = NULL;
     		d->len--;
     	}
    }
    
    

    完整代码以及示例

    #include <iostream>
    #include<stdint.h> 
    using namespace std;
    
    struct dictEntry{
    	string key;
    	string val; 
    };
    
    //字典 无序 
    struct dict{
    	dictEntry** table; //哈希表数组
    	int size; //哈希表大小
    	int len;  //键值对计数器  
    };
    
    dict* dictCreate(int size){
    	dict* d = (dict*)malloc(sizeof(dict));
    	d->table = (dictEntry**)calloc(size,sizeof(dictEntry*)); //这里要注意了 
    	for(int i=0;i<size;i++)
    		d->table[i] = NULL;
    	d->size = size;//size当作负载因子 
    	d->len=0;
    	return d;	 
    }
    
    //计算str的哈希值  参照java hashCode 
    int hash(string s){
    	int h = 0;
    	for(int i=0;i<s.length();i++){
    		h = 31 * h + (s[i] & 0xff);
    	}
    	return h;
    } 
     
    void set(dict* d,string key,string val){
    	if(d->size==d->len){
    		cout<<"哈希表满了"<<endl; 
    		return;
    	}
    	int index = hash(key)%d->size;
    	while(d->table[index]!=NULL){
    		index = (index+1)%d->size;
    	}
    	d->table[index]  = (dictEntry*)malloc(sizeof(dictEntry)); //先开辟空间 
    	d->table[index]->val = val;
    	d->table[index]->key = key;
    	d->len++;
    	return;
    }
    
    string get(dict* d,string key){
    	if(d->len==0){
    		cout<<"哈希表空的"<<endl;
    		return "";
    	}
    	int index = hash(key)%d->size;
    	int c=1;
    	while( c<d->size){
    		if(d->table[index] && d->table[index]->key==key)
    			break;
    		index = (index+1)%d->size;
    		c++;
    	}
    	if(c<d->size){
    		
    		return d->table[index]->val;	
    	}
    	else{
    		cout<<"找不到元素"<<endl;
    		return "";
    	} 
    }
    
    //根据键查找哈希表的索引 
    int getIndex(dict* d,string key){
    	if(d->len==0){
    		cout<<"哈希表空的"<<endl;
    		return -1;
    	}
    	int index = hash(key)%d->size;
    	int c=1;
    	while( c<d->size && d->table[index]->key!=key){
    		index = (index+1)%d->size;
    		c++;
    	}
    	if(c<d->size)
    		return index;
    	else{
    		cout<<"找不到元素"<<endl;
    		return -1;
    	} 
    }
    
    //根据键删除键值对 
    void DeleteByKey(dict* d,string key){
    	 int i = getIndex(d,key);
    	 if(i>=0){
     		d->table[i] = NULL;
     		d->len--;
     	}
    }
    
    
    int main(int argc, char *argv[])
    {
    	dict* d = dictCreate(100);
    	set(d,"age","1");
    	set(d,"name","biningo");
    	
    	cout<<get(d,"one");
    	
    	cout<<get(d,"age")<<" "<<get(d,"name")<<endl; 
    
    	DeleteByKey(d,"name");
    
    	cout<<get(d,"name")<<endl; 
    	return 0;
    }
    
    
    找不到元素
    1 biningo
    找不到元素
    
  • 相关阅读:
    学习TextKit框架(上)
    UITextView -- 基础备忘
    Quartz2D 备忘 + 学习
    CALayer -- 备忘
    NSURLSession -- 实际开发中运用
    NSURLSession -- 备忘
    Collection View 自定义布局(custom flow layout)
    CSS中一个冒号和两个冒号之间区别
    Chrome插件LiveStyle结合Sublime Text编辑器实现高效可视化开发
    Taking Advantage of HTML5 and CSS3 with Modernizr
  • 原文地址:https://www.cnblogs.com/biningooginind/p/12555729.html
Copyright © 2011-2022 走看看