Hash算法是一种把任意长度的数据映射转换为固定长度数据的算法,一个典型的应用就是把字符串映射到一个索引值上,这样就把字符串的查找问题变成了查表,极大的提高了性能。hash 具体算法就不介绍了,这里说说应用, 对于一个大中型的项目来说,容器类可以说是必不可少的,Array, LinkList, Que, Stack 应用最广,不过hashtable 我感觉很多人使用较少。很多场合下,使用字符名称表示对象具有更好的灵活性和更高的可扩展性,而这种应用,使用 hash table 是顺理成章的事情。下面是一个 mfc 下的封装 collection,可以通过字符名称以及索引查找 object, 这个 collection 贯穿了我的很多 projects.
#pragma once
template <class T>
class CCollection
{
CPtrArray m_objArray;
CMapStringToPtr m_objMap;
int m_Count;
public:
T* Add(LPCTSTR key, T* object)
{
m_objArray.SetAtGrow(m_Count, object);
m_objMap[key] = object;
m_Count++;
return object;
}
int GetCount()
{
return m_Count;
}
T& operator[](LPCTSTR key)
{
T* obj = (T*) m_objMap[key];
if (obj == NULL)
::AfxThrowInvalidArgException();
return *obj;
}
T& operator[](int index)
{
ASSERT(index >=0 && index < m_Count);
return *(T*) m_objArray.GetAt(index);
}
T* GetAt(LPCTSTR key)
{
return (T*) m_objMap[key];
}
T* GetAt(int index)
{
ASSERT(index >=0 && index < m_Count);
return (T*) m_objArray.GetAt(index);
}
void RemoveAll()
{
m_objArray.RemoveAll();
m_objMap.RemoveAll();
}
void DeleteAll()
{
for (int i=0; i<GetCount(); i++)
delete GetAt(i);
}
CCollection(): m_objMap(8)
{
m_objArray.SetSize(8, 4);
m_Count = 0;
}
~CCollection()
{
}
};
C# 下类似的container:
public class CCollectionBase : NameObjectCollectionBase
{
public CCollectionBase()
{
}
public CCollectionBase(int N) : base(N)
{
}
public object Add(string key, object obj)
{
base.BaseSet(key, obj);
return obj;
}
public object Put(string key, object obj)
{
base.BaseAdd(key, obj);
return obj;
}
public string GetKey(int index)
{
return base.BaseGetKey(index);
}
public object this[int index]
{
get { return (object) (base.BaseGet(index)); }
set { base.BaseSet(index, value); }
}
public object this[string key]
{
get { return (object) (base.BaseGet(key)); }
set { base.BaseSet(key, value); }
}
public CCollectionBase GetCollection(string key)
{
return (CCollectionBase) (base.BaseGet(key));
}
public string[] AllKeys
{
get { return (this.BaseGetAllKeys()); }
}
public object[] AllValues
{
get { return (this.BaseGetAllValues()); }
}
public void Remove(string key)
{
base.BaseRemove(key);
}
public void Remove(int index)
{
base.BaseRemoveAt(index);
}
public void Clear()
{
base.BaseClear();
}
public new IEnumerator GetEnumerator()
{
for (int i = 0; i < Count; i++)
yield return base.BaseGet(i);
}
模板类型:
public class CCollection<T> : CCollectionBase, IEnumerable<T>
{
public CCollection()
{
}
public CCollection(int N)
: base(N)
{
}
public T Add(string key, T obj)
{
base.BaseSet(key, obj);
return obj;
}
public T Put(string key, T obj)
{
base.BaseAdd(key, obj);
return obj;
}
public new T this[int index]
{
get { return (T) (base.BaseGet(index)); }
set { this.BaseSet(index, value); }
}
public new T this[string key]
{
get { return (T) (base.BaseGet(key)); }
set { this.BaseSet(key, value); }
}
public new IEnumerator<T> GetEnumerator()
{
for (int i = 0; i<Count; i++)
yield return (T) base.BaseGet(i);
}
}
很早以前的 C++.net (for dotnet 1.0) 下的一个 container:
public __gc class CCollection
{
private:
ArrayList* m_pArray;
Hashtable* m_pTable;
public:
Object* Add(String* key, Object* object)
{
m_pArray->Add(object);
m_pTable->Add(static_cast<Object*>(key), object);
return object;
}
__property int get_Count() { return m_pTable->Count; }
__property Object* get_Item(String* key)
{
return static_cast<Object*>(m_pTable->Item[key]);
}
__property Object* get_Item(int index)
{
return static_cast<Object*>(m_pArray->Item[index]);
}
CCollection(int N)
{
m_pArray = new ArrayList(N);
m_pTable = new Hashtable(N);
}
CCollection()
{
m_pArray = new ArrayList();
m_pTable = new Hashtable();
}
};