哈希算法是怎么实现的
有想过hash["A1"] = DateTime.Now;这句是怎么实现的吗?我们来重温下学校时代就学过的哈希算法吧。
我们要写个class,实现如下主程序调用:
static void Main(string[] args) { MyHash hash = new MyHash(); hash["A1"] = DateTime.Now; hash["A2"] = 1; Console.WriteLine(Convert.ToString(hash["A1"])); Console.WriteLine(Convert.ToString(hash["A2"])); }
一看,也确实挺简单的,就是一个所引器,如下:
class MyHash { public object this[string key] { get { } set { } } }
程序中要保存的对象,最终是要保存在一个数组中的,而且需要通过一个转换函数来进行string key与数组Index的Map,如下:
private List<List<Tuple<string, object>>> lstArray = new List<List<Tuple<string, object>>>(defaultSize); private int MapString2Int(string key) { int hashIndex=0; char[] keyAry = key.ToCharArray(); foreach (var c in keyAry) hashIndex += (int)c; hashIndex = hashIndex % lstArray.Capacity; return hashIndex; }
这个函数是遍历string key的每个char,累加,最终取模(同数组的长度),这样得出的一个value肯定就在数组范围内。
如果2个key转换出来的index相同呢?会导致冲突,一个最简单的解决办法是把数组中的每个元素变成List, 也就是说,如果string key转换后出现了相同的Index,没关系,只要把那2个元素都放在那个Index所标识的数组位置中即可,本文中用的是List<Tuple<string, object>>。
下面是整个程序的代码:
class Program { static void Main(string[] args) { MyHash hash = new MyHash(); hash["A1"] = DateTime.Now; hash["A2"] = 1; Console.WriteLine(Convert.ToString(hash["A1"])); Console.WriteLine(Convert.ToString(hash["A2"])); } } class MyHash { private const int defaultSize = 99999; private List<List<Tuple<string, object>>> lstArray = new List<List<Tuple<string, object>>>(defaultSize); public MyHash() { int i = lstArray.Capacity; while(i>=0) { lstArray.Add(new List<Tuple<string,object>>()); i--; } } public object this[string key] { get { EnsureNotNull(key); List<Tuple<string, object>> lst; Tuple<string, object> obj = FindByKey(key, out lst); if (obj == null) throw new Exception("Key不存在"); return obj.Item2; } set { EnsureNotNull(key); List<Tuple<string, object>> lst; Tuple<string, object> obj = FindByKey(key, out lst); if (obj!=null) lst.Remove(obj); lst.Add(new Tuple<string, object>(key, value)); } } private Tuple<string, object> FindByKey(string key, out List<Tuple<string, object>> lst) { int hashIndex = MapString2Int(key); lst = lstArray[hashIndex]; Tuple<string, object> obj = null; for (var i = 0; i < lst.Count; i++) { if (lst[i].Item1 == key) { obj = lst[i]; break; } } return obj; } private static void EnsureNotNull(string key) { if (key == null || key.Trim().Length == 0) throw new Exception("Key不能为空"); } private int MapString2Int(string key) { int hashIndex=0; char[] keyAry = key.ToCharArray(); foreach (var c in keyAry) hashIndex += (int)c; hashIndex = hashIndex % lstArray.Capacity; Console.WriteLine(string.Format("{0}相应的Index为:{1}", key, hashIndex)); return hashIndex; } }
运行效果图:
自省推动进步,视野决定未来。
心怀远大理想。
为了家庭幸福而努力。
商业合作请看此处:https://www.magicube.ai
心怀远大理想。
为了家庭幸福而努力。
商业合作请看此处:https://www.magicube.ai
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】