class form1
   {
        List<myst> ma = new List<myst>();
        private void button3_Click(object sender, EventArgs e)
        {
            myst axx; //速度非常慢 前几天问了下,有人说要改哈希算法,可是我尝试了多次修改都得不到好的方法.
            for (int ii = 1; ii <= 1000000; ii++)
            {
                axx = new myst();
                axx.ma = ii; axx.mb =ii;
                mc.Add(axx, ii);
            }
        }
        private static  int mhc = 0;
        struct myst
        {
            public int ma;
            public int mb;
            public override int GetHashCode()
            {
                //?? 该怎么改写它的哈希算法才能更高效呢?? 谁能给点提示吗?
            }
        }
    }

解决方案 »

  1.   

    人家是告诉你使用哈希表(HashTable)吧, 给你两个HashTable的实例, 你看懂了,也就会用了.实例一:
    //10:28 2009-6-15
    //在哈希表中添加一个key/value键值对: HashtableObject.Add(key,value);
    //在哈希表中去除某个key/value键值对: HashtableObject.Remove(key);
    //从哈希表中移除所有元素:          HashtableObject.Clear();
    //判断哈希表是否包含特定键key:      HashtableObject.Contains(key);using System;
    using System.Collections;       //使用Hashtable时,必须引入这个命名空间class hashtable
    {
    public static void Main()
    {
    Hashtable ht=new Hashtable();  //创建一个Hashtable实例
    ht.Add("E","eeee");         //添加key/value键值对
    ht.Add("A","aaaa");
    ht.Add("C","cccc");
    ht.Add("B","bbbb"); //遍历哈希表需要用到 DictionaryEntry Object
    foreach(DictionaryEntry de in ht) //ht为一个Hashtable实例
    {
                Console.Write(de.Key + "  ");    //de.Key对应于key/value键值对key
    Console.WriteLine(de.Value); //de.Key对应于key/value键值对value
    } //对哈希表进行排序, 别忘了导入System.Collections
    ArrayList akeys=new ArrayList(ht.Keys);
    akeys.Sort();           //按字母顺序进行排序
            foreach (string skey in akeys)
    {
    Console.Write(skey + ":");
    Console.WriteLine(ht[skey]); //排序后输出
    } string s=(string)ht["A"];
    Console.WriteLine(s); if(ht.Contains("E"))       //判断哈希表是否包含特定键,其返回值为true或false
    Console.WriteLine("the E key:exist"); ht.Remove("C");         //移除一个key/value键值对
    Console.WriteLine(ht["A"]);     //此处输出a
    ht.Clear();             //移除所有元素
    Console.WriteLine(ht["A"]);  //此处将不会有任何输出 Console.ReadKey();
    }
    }
      

  2.   

    实例二:
    /*
     * 员工字典示例之SocialSecurityNumbers              C#高级编程(第四版)  P238
     * 
     */
    using System;
    using System.Text;
    using System.Collections;namespace Wrox.ProCSharp.SocialSecurityNumbers
    {
        class MainEntryPoint
        {
            static void Main()
            {
                TestHarness harness = new TestHarness();
                harness.Run();
            }
        }    class TestHarness
        {
            Hashtable employees = new Hashtable(31);        public void Run()
            {
                EmployeeID idMortimer = new EmployeeID("B001");
                EmployeeData mortimer = new EmployeeData(idMortimer, "Mortimer", 100000.00M);
                EmployeeID idArabel = new EmployeeID("W234");
                EmployeeData arabel = new EmployeeData(idArabel, "Arabel Jones", 10000.00M);            employees.Add(idMortimer, mortimer);
                employees.Add(idArabel, arabel);                        // 建立两个员工信息并把它们添加到字典中            while (true)
                {
                    try
                    {
                        Console.Write("Enter employee ID (format:A999, X to exit)> ");
                        string userInput = Console.ReadLine();
                        userInput = userInput.ToUpper();
                        if (userInput == "X")
                            return;
                        EmployeeID id = new EmployeeID(userInput);
                        DisplayData(id);                                // 如果EmployeeID构造正确,就调用DisplayData方法显示相关的员工数据
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Exception occurred. Did you use the correct format for the employee ID?");
                        Console.WriteLine(e.Message);
                        Console.WriteLine();
                    }                Console.WriteLine();
                }
            }
            private void DisplayData(EmployeeID id)
            {
                object empobj = employees[id];
                if (empobj != null)
                {
                    EmployeeData employee = (EmployeeData)empobj;       // 显示员工信息
                    Console.WriteLine("Employee: " + employee.ToString());
                }
                else
                    Console.WriteLine("Employee not found: ID = " + id);
            }
        }    class EmployeeData                      // 存储员工数据的值类
        {
            private string name;
            private decimal salary;
            private EmployeeID id;        public EmployeeData(EmployeeID id, string name, decimal salary)
            {
                this.id = id;
                this.name = name;
                this.salary = salary;
            }
            public override string ToString()
            {
                StringBuilder sb = new StringBuilder(id.ToString(), 100);
                sb.Append(": ");
                sb.Append(string.Format("{0,-20}", name));
                sb.Append(" ");
                sb.Append(string.Format("{0:C}", salary));
                return sb.ToString();
            }
        }
        class EmployeeID                        // 用于标识员工的键类, 所有的操作都基于该类
        {
            private readonly char prefix;
            private readonly int number;        public EmployeeID(string id)
            {
                prefix = (id.ToUpper())[0];
                number = int.Parse(id.Substring(1, 3));
            }
            public override string ToString()
            {
                return prefix.ToString() + string.Format("{0,3:000}", number);
            }
            // 使用Microsoft提供的散列算法生成分布均匀的数字, 以满足散列代码的要求. 缺点是把EmployeeID类转换为string时会有一些性能损失.
            // 自定义散列算法的简单方法是把基于类中成员字段的数字乘以不同的素数, 如: return (int)Prefix*13+(int)number*53; 该缺点是由不
            // 同EmployeeID生成的散列代码分布在int取值范围内的均匀度比较低.
            public override int GetHashCode()
            {
                string str = this.ToString();
                return str.GetHashCode();
            }
            public override bool Equals(object obj)     // 重写Equals, 用于比较EmployeeID实例的值
            {
                EmployeeID rhs = obj as EmployeeID;
                if (rhs == null)
                    return false;
                if (prefix == rhs.prefix && number == rhs.number)
                    return true;
                return false;
            }
        }
    }
      

  3.   

    对于你写的这个结构体,最好是将ma和mb相乘,然后除以一个比字典数据量(你的示例中是100000)稍大的质数就可以了,下面是示例代码    public override int GetHashCode()
        {
            int prime;      //prime为比字典稍大的质数        return ma * mb / prime;
        }