Map/HashMap其存储是没有顺序的,而TreeMap则是有序存储。
参考链接:
http://blog.csdn.net/devillyd/article/details/3135479
http://coolshell.cn/articles/9703.html
import java.util.Map; import java.util.HashMap; import java.util.Set; import java.util.HashSet; import java.util.Iterator; import java.util.Hashtable; import java.util.TreeMap; class HashMaps { public static void main(String[] args) { Map map=new HashMap(); map.put("a", "aaa"); map.put("b", "bbb"); map.put("c", "ccc"); map.put("d", "ddd"); Iterator iterator = map.keySet().iterator(); while (iterator.hasNext()) { Object key = iterator.next(); System.out.println("map.get(key) is :"+map.get(key)); } Hashtable tab=new Hashtable(); tab.put("a", "aaa"); tab.put("b", "bbb"); tab.put("c", "ccc"); tab.put("d", "ddd"); Iterator iterator_1 = tab.keySet().iterator(); while (iterator_1.hasNext()) { Object key = iterator_1.next(); System.out.println("tab.get(key) is :"+tab.get(key)); } TreeMap tmp=new TreeMap(); tmp.put("a", "aaa"); tmp.put("b", "bbb"); tmp.put("c", "ccc"); tmp.put("d", "ddd"); Iterator iterator_2 = tmp.keySet().iterator(); while (iterator_2.hasNext()) { Object key = iterator_2.next(); System.out.println("tmp.get(key) is :"+tmp.get(key)); } } }运行结果如下:
map.get(key) is :ddd map.get(key) is :bbb map.get(key) is :ccc map.get(key) is :aaa tab.get(key) is :bbb tab.get(key) is :aaa tab.get(key) is :ddd tab.get(key) is :ccc tmp.get(key) is :aaa tmp.get(key) is :bbb tmp.get(key) is :ccc tmp.get(key) is :ddd
hash_map散列表本身不在ISO的STL和C++标准库中,不属于标准的一部分,不适用于跨编译器使用。一个编译器能用,另一个可能不能用。比如gcc下,hash_map已经被归为旧版兼容的工具,需要用__gnu_cxx::hash_map名字空间才能使用,而非标准的std::推荐用符合ISO标准map容器(红黑树表)替代。如果没有明显的性能差距,多用map而不是hash_map。
按照hashmap的基本原理用C++实现了简单的基本功能,复杂的实现参考C++库的源码,C++最新的标准库里已经有以下四种基于hashtable的容器:
unordered_set(C++11)unordered_multiset(C++11)unordered_map(C++11)unordered_multimap (C++11)。
具体参考:http://en.cppreference.com/w/
http://www.cnblogs.com/luxiaoxun/archive/2012/09/02/2667782.html
#include <string> #include <iostream> #include <ext/hash_map> using namespace std; using namespace __gnu_cxx; struct str_hash { size_t operator() (const string & s) const { return __stl_hash_string(s.c_str()); }}; struct str_compare { int operator() (const string & a, const string & b) const { return (a == b); }}; typedef hash_map < string, string, str_hash, str_compare > StrMap; int main() { StrMap strMap; string a, b; cout << "鎻掑叆:" << endl; while (cin >> a >> b) { if (a.length() <= 1) break; strMap.insert(make_pair(a, b)); } cout << "鏌ヨ:" << endl; while (cin >> a) { if (a.length() <= 1) break; if (strMap.find(a) != strMap.end()) cout << strMap[a] << endl; else cout << "not found" << endl; } return 0; }
利用unordered_map实现如下:
/* * ===================================================================================== * * Filename: unordered_map.cc * * Description: * * Version: 1.0 * Created: 2014年01月17日 16时38分01秒 * Revision: none * Compiler: gcc * * Author: lishuming (think different and do it with plearsure.), [email protected] * Organization: RADI A401 * * ===================================================================================== */ #include <iostream> #include <unordered_map> #include <string> using namespace std; unsigned int JSHash(const char *str) { unsigned int hash = 1315423911; while (*str) { hash ^= ((hash << 5) + (*str++) + (hash >> 2)); } return (hash & 0x7FFFFFFF); } struct StrHash { size_t operator() (const string & s) const { return JSHash(s.c_str()); }}; struct StrCompare { bool operator() (const string & a, const string & b) const { return a == b; }}; typedef unordered_map < string, string, StrHash, StrCompare > MyMap; int main() { MyMap mymap; string a, b; while (cin >> a >> b) { mymap[a] = b; } for (MyMap::iterator it = mymap.begin(); it != mymap.end(); ++it) cout << it->first << " " << it->second << endl; return 0; }
HashMap 利用C++的具体实现
/* * ===================================================================================== * * Filename: HashMap.h * * Description: * * Version: 1.0 * Created: 2014年01月17日 16时56分40秒 * Revision: none * Compiler: gcc * * Author: lishuming (think different and do it with plearsure.), [email protected] * Organization: RADI A401 * * ===================================================================================== */ /* * HashMap.h * Author: luxiaoxun */ #ifndef HASHMAP_H_ #define HASHMAP_H_ #include <iostream> using namespace std; //List all the integer number no less than 57 total number is 28 //And each number is about half of its next number static int prime[28] = { 57, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593, 49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469, 12582917, 25165843, 50331653, 100663319, 201326611, 402653189, 805306457, }; class HashMapUtil { public: static int find_NextPrimeNumber(int current) { //Find the next prime number by searching in the prime number list int i = 0; for (; i < 28; i++) if (current < prime[i]) break; return prime[i]; //return the next larger prime. } }; template < class Key, class Value, class HashFunc, class EqualKey > class HashMap { private: template < class _Key, class _Value > class KeyNode { public: _Value value; //Store the value _Key key; //Store the keyword int used; //if the type of Value/Key is your own class, make sure they can handle copy constructor and operator = KeyNode():used(0) { } KeyNode(const KeyNode & kn) { value = kn.value; key = kn.key; used = kn.used; } KeyNode & operator=(const KeyNode & kn) { if (this == &kn) return *this; value = kn.value; key = kn.key; used = kn.used; return *this; } }; public: HashMap(); ~HashMap(); bool insert(const Key & hashKey, const Value & value); bool remove(const Key & hashKey); void rehash(); //use it when rehashing Value & find(const Key & hashKey); const Value & operator [] (const Key & hashKey) const; Value & operator [](const Key & hashKey); private: HashFunc hash; EqualKey equal; HashMapUtil hml; KeyNode < Key, Value > *table; int size; //current number of itmes int capacity; //capacity of the array static const double loadingFactor; int findKey(const Key & hashKey); //find the index of a key }; template < class Key, class Value, class HashFunc, class EqualKey > const double HashMap < Key, Value, HashFunc, EqualKey >::loadingFactor = 0.9; template < class Key, class Value, class HashFunc, class EqualKey > HashMap < Key, Value, HashFunc, EqualKey >::HashMap() { hash = HashFunc(); equal = EqualKey(); hml = HashMapUtil(); capacity = hml.find_NextPrimeNumber(0); //initialize the capacity with first primer 57 //resize the table with capacity because an extra one is used //to return the NULL type of Value in the function find table = new KeyNode < Key, Value >[capacity + 1]; for (int i = 0; i < capacity; i++) //initialize the table table[i].used = 0; size = 0; } template < class Key, class Value, class HashFunc, class EqualKey > HashMap < Key, Value, HashFunc, EqualKey >::~HashMap() { delete[]table; } template < class Key, class Value, class HashFunc, class EqualKey > bool HashMap < Key, Value, HashFunc, EqualKey >::insert(const Key & hashKey, const Value & value) { int index = hash(hashKey) % capacity; //cout<<"Index is "<<index<<endl; if (table[index].used == 1) //the key-value's hash is unique { //cout<<"The key-value must be unique!"<<endl; return false; } table[index].used = 1; //modify the KeyNode table[index].key = hashKey; table[index].value = value; size++; //if the table's size is too large ,then rehash it if (size >= capacity * loadingFactor) rehash(); return true; } template < class Key, class Value, class HashFunc, class EqualKey > void HashMap < Key, Value, HashFunc, EqualKey >::rehash() { int pastsize = capacity; //create a new array to copy the information in the old table capacity = hml.find_NextPrimeNumber(capacity); KeyNode < Key, Value > *tmp = new KeyNode < Key, Value >[capacity]; for (int i = 0; i < pastsize; i++) { if (table[i].used == 1) //copy the KeyNode into the tmp array { tmp[i] = table[i]; } } delete[]table; //release the memory of the old table table = new KeyNode < Key, Value >[capacity + 1]; //resize the table for (int i = 0; i < capacity; i++) //initialize the table { table[i].used = 0; } for (int i = 0; i < pastsize; i++) //insert the item into the table one by one { if (tmp[i].used == 1) insert(tmp[i].key, tmp[i].value); } delete[]tmp; //delete the tmp array } template < class Key, class Value, class HashFunc, class EqualKey > bool HashMap < Key, Value, HashFunc, EqualKey >::remove(const Key & hashKey) { int index = findKey(hashKey); //find the index of the key if (index < 0) //if find modify the flag with 0,else print out "no such key!" { cout << "No such Key!" << endl; return false; } else { table[index].used = 0; size--; return true; } } template < class Key, class Value, class HashFunc, class EqualKey > Value & HashMap < Key, Value, HashFunc, EqualKey >::find(const Key & hashKey) { int index = findKey(hashKey); if (index < 0) //if index <0 ,not found,else return the index { cout << "can not find the key!" << endl; return table[capacity].value; //return NULL } else { return table[index].value; } } template < class Key, class Value, class HashFunc, class EqualKey > const Value & HashMap < Key, Value, HashFunc, EqualKey >::operator[] (const Key & hashKey) const { return find(hashKey); //overload the operation to return the value of the element } template < class Key, class Value, class HashFunc, class EqualKey > Value & HashMap < Key, Value, HashFunc, EqualKey >::operator[] (const Key & hashKey) { return find(hashKey); //overload the operation to return the value of the element } template < class Key, class Value, class HashFunc, class EqualKey > int HashMap < Key, Value, HashFunc, EqualKey >::findKey(const Key & hashKey) { int index = hash(hashKey) % capacity; if ((table[index].used != 1) || !equal(table[index].key, hashKey)) return -1; else return index; } #endif /* HASHMAP_H_ */
/* * ===================================================================================== * * Filename: HahMap.cpp * * Description: * * Version: 1.0 * Created: 2014年01月17日 16时57分03秒 * Revision: none * Compiler: gcc * * Author: lishuming (think different and do it with plearsure.), [email protected] * Organization: RADI A401 * * ===================================================================================== */ #include "HashMap.h" #include <string> #include <iostream> using namespace std; //Hash function you provided must be correspond to the type of the Key class HashFunc { public: int operator() (const string & key) { int hash = 0; for (int i = 0; i < key.length(); ++i) { hash = hash << 7 ^ key[i]; } return (hash & 0x7FFFFFFF); } }; //Equal function you provided to check whether two Keys are equal //must be correspond to the type of the Key class EqualKey { public: bool operator() (const string & A, const string & B) { if (A.compare(B) == 0) return true; //if equal return true else return false; //else false }}; int main() { HashMap < string, string, HashFunc, EqualKey > hm; hm.insert("hello", "you"); hm.insert("why", "dream"); hm.insert("java", "good"); hm.insert("welcome", "haha"); hm.insert("welcome", "hehe"); //error, key-value must be unique cout << "after insert:" << endl; cout << hm.find("welcome") << endl; cout << hm.find("java") << endl; cout << hm["why"] << endl; cout << hm["hello"] << endl; if (hm.remove("hello")) cout << "remove is ok" << endl; //remove is ok cout << hm.find("hello") << endl; //not exist print NULL hm["why"] = "love"; //modify the value cout << hm["why"] << endl; return 0; }