📜  C#中字符串数据的哈希函数

📅  最后修改于: 2021-05-29 17:39:20             🧑  作者: Mango

问题:用C#编写代码以哈希键数组并显示其哈希码。

答: Hashtable是一种广泛使用的数据结构,用于存储用其哈希码索引的值(即键)。哈希码是哈希函数的结果,并用作存储键的索引的值。如果两个不同的键散列为相同的值,则将这种情况称为冲突,并且良好的散列函数最大程度地减少冲突。

问题:如何选择适合数据的哈希函数?

答:如果您的数据由整数组成,那么最简单的哈希函数是返回键除法的剩余部分和表的大小。重要的是要保持表的大小为质数。但是可以编写更复杂的函数来避免冲突。如果您的数据由字符串组成,则可以将字母的所有ASCII值相加,然后将和与表的大小取模(以下代码对此进行了描述)。

范例1:

// C# Program to create a Hash 
// Function for String data
using System;
  
class Geeks {
      
    // Main Method
    public static void Main(String []args)
    {
          
        // Declaring the an string array
        string[] values = new string[50];
        string str;
  
        // Values of the keys stored
        string[] keys = new string[] {"Alphabets", 
              "Roman", "Numbers", "Alphanumeric", 
                                  "Tallypoints"};
  
        int hashCode;
  
        for (int k = 0; k < 5; k++) {
              
            str = keys[k];
              
            // calling HashFunction
            hashCode = HashFunction(str, values);
  
            // Storing keys at their hashcode's index
            values[hashCode] = str;
        }
  
        // Displaying Hashcodes along with key values
        for (int k = 0; k < (values.GetUpperBound(0)); k++) {
              
            if (values[k] != null)
                Console.WriteLine(k + " " + values[k]);
        }
    }
  
    // Defining the hash function
    static int HashFunction(string s, string[] array)
    {
        int total = 0;
        char[] c;
        c = s.ToCharArray();
  
        // Summing up all the ASCII values 
        // of each alphabet in the string
        for (int k = 0; k <= c.GetUpperBound(0); k++)
            total += (int)c[k];
  
        return total % array.GetUpperBound(0);
    }
}
输出:
11 Tallypoints
16 Alphanumeric
19 Roman
34 Alphabets
46 Numbers

范例2:

// C# Program to create a Hash 
// Function for String data
using System;
  
class Geeks {
      
    // Main Method
    public static void Main(String []args)
    {
          
        // Declaring the an string array
        string[] values = new string[50];
        string str;
  
        // Values of the keys stored
        string[] keys = new string[] {"C", "C++", 
                 "Java", "Python", "C#", "HTML"};
  
        int hashCode;
  
        for (int k = 0; k < 5; k++) {
              
            str = keys[k];
            hashCode = HashFunction2(str, values);
  
            // Storing keys at their hashcode's index
            values[hashCode] = str;
        }
  
        // Displaying Hashcodes along with key values
        for (int k = 0; k < (values.GetUpperBound(0)); k++) {
              
            if (values[k] != null)
                Console.WriteLine(k + " " + values[k]);
        }
    }
  
    // Defining the hash function
    static int HashFunction2(string s, string[] array)
    {
        long total = 0;
        char[] c;
        c = s.ToCharArray();
  
        // Horner's rule for generating a polynomial 
        // of 11 using ASCII values of the characters
        for (int k = 0; k <= c.GetUpperBound(0); k++)
          
            total += 11 * total + (int)c[k];
  
        total = total % array.GetUpperBound(0);
          
        if (total < 0)
            total += array.GetUpperBound(0);
  
        return (int)total;
    }
}
输出:
6 C#
15 C++
18 C
19 Python
28 Java

解释:散列函数,我们通过参数作为要被散列的字符串和字符串数据“价值”。 ToCharArray方法将字符串转换为字符数组,然后从字符数组的开始到结尾开始for循环。在for循环内,我们计算数组中每个字符的ASCII值的总和。方法GetUpperBound返回数组最高索引的值。然后,哈希函数以数组的上限返回总和的模(在本例中为49,因为字符串[]的值=新字符串[50] )。在HashFunction2中,我们传递相同的参数,但是此函数发生冲突的可能性较小。除了这里我们使用霍纳法则来计算11的多项式函数外,其他所有内容基本上都是相同的。