zoukankan      html  css  js  c++  java
  • hash_table


    1
    //哈希表查询与插入删除速率非常快速 2 #include<unordered_map> 3 #include<map> 4 #include<iostream> 5 6 using namespace std; 7 template<typename Key,typename Value> 8 class HashTable 9 { 10 private: 11 const static int upperTol = 3; 12 const static int lowerTol = 1; 13 const static int initCapacity = 1; 14 map<Key,Value> **hashtable;//整个表 15 int M;//哈希表数组的大小 16 int size;//表中已有元素个数 17 18 public: 19 //传参构造 20 HashTable(int m) : M((m),size(0) 21 { 22 //this->hashtable = new map<Key,Value>* [M](); 23 this->hashtable = new map<Key,Value>* [M]; 24 for (inti= 0;i < M;i++) 25 { 26 this->hashtable[i] = new map<Key,Value>; 27 } 28 } 29 //默认构造 30 HashTable() { 31 HashTable(initCapacity); 32 } 33 34 //析构函数 35 ~HashTable() { 36 free(M); 37 } 38 39 public: 40 int getSize() { 41 return size; 42 } 43 44 //添加新元素 45 void add(Key key,Value value) 46 {// 拉链法出来的map如果为空,就动态分配一个map,然后进行插入 47 // 如果key不存在就看内存是否存在,不存在,就分配,存在就插入 48 if (hashtable[hashFunc(key)] == NULL || hashtable[hasFunc(key)]->count(key) == 0)//count() 49 { if (hashtable[hashFunc(key)] == NULL) 50 hashtable[hashFunc(key)] = new map<Key, Value>; 51 hashtable[hashFunc(key)]->insert(make_pair(key, value)); 52 size++; 53 if (size >= maxCapacity()) 54 resize(2 * M); 55 } else { 56 // 否则,修改value. 57 hashtable[hashFunc(key)]->erase(key); 58 hashtable[hashFunc(key)]->insert(make_pair(key, value)); 59 } 60 } 61 /** 62 * 移除Key 63 * @param key 64 * @return 0 success -1 fail 65 */ 66 Value remove(Key key) { 67 Value ret = -1; 68 // 是否包含key,若包含key,则直接删除 69 if (contains(key)) { 70 hashtable[hashFunc(key)]->erase(key); 71 size--; 72 // if (size == 0) delete hashtable[hashFunc(key)]; // 可以添加这行来动态减少内存 73 ret = 0; 74 // initCapacity 保证不会越界 75 if (size < minCapacity() && M / 2 >= initCapacity) resize(M / 2); 76 } 77 return ret; 78 } 79 80 /** 81 * 重设value 82 * @param key 83 * @param value 84 */ 85 void set(Key key, Value value) { 86 // key不存在 87 if (!contains(key)) 88 throw "key not exists!"; 89 // 修改value 90 hashtable[hashFunc(key)]->erase(key); 91 hashtable[hashFunc(key)]->insert(make_pair(key, value)); 92 } 93 /** 94 * 是否包含key 95 * @param key 96 * @return 97 */ 98 bool contains(Key key) { 99 return hashtable[hashFunc(key)] == NULL || this->hashtable[hashFunc(key)]->count(key) == 0 ? false : true; 100 } 101 102 /** 103 * 获取key对应的value 104 * @param key 105 * @return 106 */ 107 108 Value get(Key key) { 109 if (contains(key)) 110 return hashtable[hashFunc(key)]->at(key); 111 return 0; 112 } 113 114 /** 115 * 最大容量 116 * @return 117 */ 118 Value maxCapacity() { 119 return M * upperTol; 120 } 121 122 /** 123 * 最小容量 124 * @return 125 */ 126 Value minCapacity() { 127 return M * lowerTol; 128 } 129 130 private: 131 /** 132 * 哈希函数 133 * @param key 134 * @return 135 */ 136 int hashFunc(Key key) { 137 std::hash<Key> h; 138 return (h(key) & 0x7fffffff) % M; 139 } 140 141 template<typename K, typename V> 142 // 重载<<操作符 143 friend ostream &operator<<(ostream &out, HashTable<K, V> &hashTable); 144 145 /** 146 * 打印hash表中所有数据 147 */ 148 void print() { 149 string res = "{"; 150 for (int i = 0; i < this->M; i++) 151 if (this->hashtable[i]) 152 for (auto m:*(this->hashtable[i])) 153 res += m.first + ":" + to_string(m.second) + ","; 154 res.replace(res.size() - 1, string::npos, "}");//将最后一个字符串替换
    //npos是一个静态成员常量值,对于size_t类型的元素,其最大值可能

    该值字符串成员函数中用作len(或sublen)参数的值时,表示“直到字符串结尾” 作为返回值,通常用于表示没有匹配项。 该常量定义为值-1,这是因为size_t是无符号整数类型,因此它是此类型可能的最大可表示值。
    155 cout << res << endl; 156 } 157 158 /** 159 * 动态调整内存,保证时间复杂度O(1)查找 160 * 把扩容后的操作,平摊到前面每次操作,时间复杂度O(2),那就是O(1)了 161 * @param newM 162 */ 163 void resize(int newM) {
            //首先获取新的空间,再将旧的数据复制到新的空间,最后释放旧空间
    164 cout << "resize " << newM << endl; 165 map<Key, Value> **newHashTable = new map<Key, Value> *[newM]; 166 for (int i = 0; i < newM; i++) { 167 newHashTable[i] = new map<Key, Value>; 168 } 169 int oldM = M; 170 this->M = newM; 171 for (int i = 0; i < oldM; i++) { 172 map<Key, Value> m = *(hashtable[i]); 173 for (auto p:m) 174 newHashTable[hashFunc(p.first)]->insert(make_pair(p.first, p.second)); 175 } 176 177 178 free(oldM); 179 this->hashtable = newHashTable; 180 } 181 182 private: 183 /** 184 * 释放内存 185 * @param M 186 */ 187 void free(int M) { 188 for (int i = 0; i < M; i++) { 189 if (hashtable[i]) 190 delete hashtable[i]; 191 } 192 delete[]hashtable; 193 } 194 }; 195 196 template<typename K, typename V> 197 ostream &operator<<(ostream &out, HashTable<K, V> &hashTable) { 198 hashTable.print(); 199 return out; 200 } 201 202 /** 203 * 哈希函数的设计原则: 204 * 1.一致性:如果a==b,则hashFunc(a)=o=hashFunc(b) 205 * 2.高效性:计算高效简便 206 * 3.均匀性:哈希值均匀分布 207 */ 208 209 // (hashcode(k1) & 0x7fffffff)%M 210 // f为7个一个f有4个1那么就是28个1,,7有3个1,,总共31个1 211 // 而最高位第32位表示正负,故上述取&后,变为正数。 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 };

    哈希表:以map作为底部容器,由装多个map地址的数组和多个map构成。
    map:所有元素都唯一,且所有元素自动从小到大排序

    1)map::count()----根据键值查看map中是否由此节点
     1 #include<iostream>
     2 #include<map>
     3 int main()
     4 {
     5   std::map<char,int> mymap;
     6   char c;
     7 
     8   mymap['a'] = 101;
     9   mymap['b'] = 202;
    10   mymap['c'] = 303;
    11 
    12   for (c = 'a';c < 'e';c++)
    13   {
    14     std::cout << c << endl;
    15     if (mymap.count(c) > 0)
    16       std::cout <<"is an element
    ";
    17     else
    18       std::cout << "is not an element
    ";
    19   }
    20   
    21 }
    2)map::insert()---插入节点
     1 #include <iostreram>
     2 #include <map>
     3 
     4 int main()
     5 {
     6   sta::map<char,int> mymap;
     7   //first version----single parameter
     8   mymap.insert(std::pair<char,int>('a',100));
     9   mymap.insert(std::pair<char,int>('z',200));
    10   mymap.insert(std::make_pair('d',321));
    11 
    12   std::pair<std::map<char,int>::iterator,bool> ret;
    13   ret = mymap.insert(std::pair<char,int>('z',500));
    14   if (ret.second == false){
    15     std::cout << "element 'z' already existed";
    16     std::cout << "with a value of " << ret.first->second << estd::endl
    17   }
    18 //second version---with hint position
    19   std::map<char,int>::iterator it = mymap.begin();
    20   mymap.insert(it,std::pair<char,int>('b',300));
    21   mymap.insert(it,std::pair<char,int>)'c',400));
    22 
    23 //third version----range insertion
    24 std::map<char,int> anothermap;
    25 anothermap.insert(mymap.begin(),mymap.find('c));
    26 //show contents
    27 std::cout << "mymap contains:
    ";
    28 for (it = mymap.begin();it != mymap.end();it++)
    29 {
    30   std::cout << it->first << "-->" << it->second << '
    ';
    31 }
    32 
    33 std::cout << "anothermap contains:
    ";
    34 for (it = anothermap.begin();it != aonthermap.end();it++)
    35   std::cout << it->first << "-->" << it->second << '
    ' ;
    36 }

    3)string成员函数

    (1)replace

     1 #include <iostream>
     2 
     3 #include <string>
     4 
     5 int main()
     6 
     7 {
     8 
     9   std::string base = "this is a test string";
    10 
    11   std::string str2 = "n example";
    12 
    13   std::string str3 = "sample phrase";
    14 
    15   std::string str4 = "useful";
    16 
    17   //versionj1-----use position
    18 
    19   std::string str = base;
    20 
    21   str.replace(9,5,str2);
    22 
    23   str.replace(19,6,str3,7,6);
    24 
    25   str.replace(8,10,"just a");
    26 
    27   str.replace(8,6,"a shorty",7);
    28 
    29   str.replace(22,1,3,'!');
    30 
    31 
    32 
    33   //using iterator
    34 
    35   str.replace(str.begin(),str.end()-3,str3);
    36 
    37   str.replace(str.begin(),str.begin()+6,"replace");
    38 
    39   str.replace(str.begin(),str.begin+14,"is");
    40 
    41 }

    (2)string::npos

    静态const size_t npos = -1;
    size_t的最大值

    npos是一个静态成员常量值,对于size_t类型的元素,其最大值可能

    该值字符串成员函数中用作len(或sublen)参数的值时,表示“直到字符串结尾” 作为返回值,通常用于表示没有匹配项。 该常量定义为值-1,这是因为size_t是无符号整数类型,因此它是此类型可能的最大可表示值。

     

      

  • 相关阅读:
    poj 2337 欧拉回路输出最小字典序路径 ***
    hdu 4831
    hdu 4832 dp ***
    hdu 4833 离散化+dp ****
    hdu 4006 优先队列 2011大连赛区网络赛F **
    hdu 4005 双联通 2011大连赛区网络赛E *****
    hdu 4004 二分 2011大连赛区网络赛D
    hdu 4003 树形dp+分组背包 2011大连赛区网络赛C
    hdu 4002 欧拉函数 2011大连赛区网络赛B
    跨域经验总结
  • 原文地址:https://www.cnblogs.com/pengtangtang/p/12887738.html
Copyright © 2011-2022 走看看