1. Java中Map/HashMap/TreeMap的分析
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
2.GCC下C++ HashMap的表达
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.), lism2013@hotmail.com
* 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.), lism2013@hotmail.com
* 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.), lism2013@hotmail.com
* 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;
}