zl程序教程

您现在的位置是:首页 >  后端

当前栏目

c#哈希算法的实现方法及思路

2023-06-13 09:15:13 时间

有想过hash["A1"]=DateTime.Now;这句是怎么实现的吗?我们来重温下学校时代就学过的哈希算法吧。

我们要写个class,实现如下主程序调用:

复制代码代码如下:


staticvoidMain(string[]args)
       {
           MyHashhash=newMyHash();
           hash["A1"]=DateTime.Now;
           hash["A2"]=1;
           Console.WriteLine(Convert.ToString(hash["A1"]));
           Console.WriteLine(Convert.ToString(hash["A2"]));
       }

一看,也确实挺简单的,就是一个所引器,如下:

复制代码代码如下:


classMyHash
   {
       publicobjectthis[stringkey]
       {
           get
           {
           }
           set
           {
           }
       }
   }

程序中要保存的对象,最终是要保存在一个数组中的,而且需要通过一个转换函数来进行stringkey与数组Index的Map,如下:

复制代码代码如下:
privateList<List<Tuple<string,object>>>lstArray=newList<List<Tuple<string,object>>>(defaultSize);

privateintMapString2Int(stringkey)
       {
           inthashIndex=0;
           char[]keyAry=key.ToCharArray();
           foreach(varcinkeyAry)
               hashIndex+=(int)c;

           hashIndex=hashIndex%lstArray.Capacity;
           returnhashIndex;
       }

这个函数是遍历stringkey的每个char,累加,最终取模(同数组的长度),这样得出的一个value肯定就在数组范围内。

如果2个key转换出来的index相同呢?会导致冲突,一个最简单的解决办法是把数组中的每个元素变成List,也就是说,如果stringkey转换后出现了相同的Index,没关系,只要把那2个元素都放在那个Index所标识的数组位置中即可,本文中用的是List<Tuple<string,object>>。

下面是整个程序的代码:

复制代码代码如下:
classProgram
   {
       staticvoidMain(string[]args)
       {
           MyHashhash=newMyHash();
           hash["A1"]=DateTime.Now;
           hash["A2"]=1;
           Console.WriteLine(Convert.ToString(hash["A1"]));
           Console.WriteLine(Convert.ToString(hash["A2"]));
       }
   }

   classMyHash
   {
       privateconstintdefaultSize=99999;
       privateList<List<Tuple<string,object>>>lstArray=newList<List<Tuple<string,object>>>(defaultSize);

       publicMyHash()
       {
           inti=lstArray.Capacity;
           while(i>=0)
           {
               lstArray.Add(newList<Tuple<string,object>>());
               i--;
           }
       }

       publicobjectthis[stringkey]
       {
           get
           {
               EnsureNotNull(key);

               List<Tuple<string,object>>lst;
               Tuple<string,object>obj=FindByKey(key,outlst);
               if(obj==null)
                   thrownewException("Key不存在");

               returnobj.Item2;
           }
           set
           {
               EnsureNotNull(key);

               List<Tuple<string,object>>lst;
               Tuple<string,object>obj=FindByKey(key,outlst);
               if(obj!=null)
                   lst.Remove(obj);

               lst.Add(newTuple<string,object>(key,value));
           }
       }

       privateTuple<string,object>FindByKey(stringkey,outList<Tuple<string,object>>lst)
       {
           inthashIndex=MapString2Int(key);
           lst=lstArray[hashIndex];
           Tuple<string,object>obj=null;
           for(vari=0;i<lst.Count;i++)
           {
               if(lst[i].Item1==key)
               {
                   obj=lst[i];
                   break;
               }
           }

           returnobj;
       }

       privatestaticvoidEnsureNotNull(stringkey)
       {
           if(key==null||key.Trim().Length==0)
               thrownewException("Key不能为空");
       }

       privateintMapString2Int(stringkey)
       {
           inthashIndex=0;
           char[]keyAry=key.ToCharArray();
           foreach(varcinkeyAry)
               hashIndex+=(int)c;

           hashIndex=hashIndex%lstArray.Capacity;

           Console.WriteLine(string.Format("{0}相应的Index为:{1}",key,hashIndex));

           returnhashIndex;
       }
   }

运行效果图: