哈希函数C.

时间:2015-07-12 08:58:46

标签: c ascii hashtable

我在为哈希表实现哈希函数时遇到了麻烦。

我想哈希我的话,A = 1,B = 2,C = 3,依此类推。字母在单词中的位置是无关紧要的,因为我们会考虑单词的排列。此外,字母的情况也与此问题无关,因此a的值= A = 1的值。

对于字符串,abc = 1 + 2 + 3 = 6,bc = 2 + 3 = 5等

对于ab = 3和aaa = 3的情况,我已经有办法处理这种情况。现在我只想得到哈希值。

我现在遇到的问题是aaa给了我1,ab给了我2。

以下是我的代码:

int hash(char *word)
{
   int h = 1;
   int i, j;

   char *A;
   char *a;
   // an array of 26 slots for 26 uppercase letters in the alphabet
   A = (char *)malloc(26 * sizeof(char));
   // an array of 26 slots for 26 lowercase letters in the alphabet
   a = (char *)malloc(26 * sizeof(char));

   for (i = 0; i < 26; i++) {
      A[i] = (char)(i + 65); // fill the array from A to Z
      a[i] = (char)(i + 97); // fill the array from a to z
   }

   for (i = 0; i < strlen(word); i++) {
      //printf("HIT\n");
      for (j = 0; j < 26; j++) {
         // upper and lower case have the same hash value
         if (word[i] == A[j] || word[i] == a[j]) {
            h = h + j; // get the hash value of the word
            //printf("HIT 2\n");
            break;
         }
      }
   }

   printf("H: %d\n", h);

   return h;
}

3 个答案:

答案 0 :(得分:5)

我认为改变了

int h = 1;

int h = 0;

h = h + j;

h = h + j + 1;

将解决问题。

另一个问题是您忘记释放malloc内存。此外,C中有no need to cast the result of malloc(和家庭)。

for (i = 0; i < strlen(word); i++) {

将在循环的每次迭代中调用strlen。这会降低程序的性能。使用

int len = strlen(word);
for (i = 0; i < len; i++) {

相反,由于在每次迭代中都没有调用strlen,所以速度要快得多。最后,sizeof(char)是1.所以你可以省略它。

答案 1 :(得分:2)

h=h+j更改为h = h+j+1h=1h=0

此外,你应该释放分配的内存,所以在返回之前包括这些行:

free(A);
free(a);

但是我不明白为什么为这么简单的任务编写如此复杂的代码。

可以编写更简单的代码:

int hash(char *word)
{
   int sum=0;
   while(*word != '\0')
   {

       if(*word >='A' && *word < 'A'+26)
            sum=sum+(*word -'A' + 1);
       else if(*word >='a' && *word < 'a'+26)
            sum=sum+(*word -'a' + 1);
       else
            return -1;

       word++;
   }

   return sum;
}

答案 2 :(得分:2)

多个问题:

  1. 你仍然没有释放你分配的阵列
  2. h的初始值1没有意义
  3. 您将索引添加到哈希。 &#39; A&#39;和&#39; a&#39;在索引0处,因此在这种情况下您添加0(因此,无论您提供多少代码,您的代码都将返回1)
  4. 为什么是动态阵列?你知道它的大小,它不会改变。你可以用

    char A[26];
    char a[26]; // you can also add initialisation, e.g. = {'a', 'b', ...
    
  5. 为什么首先是数组?

  6. 因此,here是快速解决方案,与您的代码保持密切联系。

    考虑到以上所有因素,您可以简化为:

    int hash(char const * string) {
      int h = 0;
      for (; *string; ++string) {
        int index = tolower(*string) - 'a' + 1;
        if ((index > 0) && (index < 27)) {
          h += index;
        }
      }
      return h;
    }
    

    Live

    当只使用非特殊字符散列单词时,您需要以某种方式处理调用者中被忽略的单词。

    char hash(char const * string, int * h) {
      *h = 0;
      for (; *string; ++string) {
        int index = tolower(*string) - 'a' + 1;
        if ((index > 0) && (index < 27)) {
          *h += index;
        } else {
          return 0;
        }
      }
      return 1;
    }
    

    通过这种方式,您可以使用返回值来测试是否应该忽略该单词。