zoukankan      html  css  js  c++  java
  • 哈希算法是怎么实现的

    有想过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;
            }
        }

     运行效果图:

  • 相关阅读:
    samdump2获取虚拟机密码
    PHP执行cmd方法若干
    Aircrack-ng学习笔记之无AP破解WiFi密码
    Python基础:extend与append的区别
    Python基础:dictionary
    UVALive 3177 长城守卫
    UVALive 3902 网络
    UVA 11520 填充正方形
    UVALive 3635 分派
    UVALive 3971 组装电脑
  • 原文地址:https://www.cnblogs.com/aarond/p/Hash.html
Copyright © 2011-2022 走看看