请教字符串哈希算法

时间:2021-04-16 16:44:23
各位大虾好,我对哈希算法不太熟,不知道可不可以将不同的字符串通过哈希函数均匀地散列到一定的数值范围,这个数值范围最好和字符串的数量相同,希望大家给个思路。

5 个解决方案

#1


把字符串的每个字符乘法一遍。。看你要求什么精度

#2


数值范围最好和字符串的数量相同,

这个很难实现

#3


常用的hash有sdbm, djb2, crc32。

对于不固定的字符串集合来说,不太可能hash函数值和字符串数量相同

对于固定的字符串集合,可以把重复的去掉,给每个剩下的字符串指定一个id, 这个id可以作为一个hash

#4



// RS Hash Function
unsigned int RSHash(char *str)
{
         unsigned int b = 378551;
         unsigned int a = 63689;
         unsigned int hash = 0;

         while (*str)
         {
                 hash = hash * a + (*str++);
                 a *= b;
         }

         return (hash & 0x7FFFFFFF);
}

// JS Hash Function
unsigned int JSHash(char *str)
{
         unsigned int hash = 1315423911;

         while (*str)
         {
                 hash ^= ((hash << 5) + (*str++) + (hash >> 2));
         }
        
         return (hash & 0x7FFFFFFF);
}

// P. J. Weinberger Hash Function
unsigned int PJWHash(char *str)
{
         unsigned int BitsInUnignedInt = (unsigned int)(sizeof(unsigned int) * 
8);
         unsigned int ThreeQuarters     = (unsigned int)((BitsInUnignedInt   * 3)
/ 4);
         unsigned int OneEighth         = (unsigned int)(BitsInUnignedInt / 8);

         unsigned int HighBits          = (unsigned int)(0xFFFFFFFF) << (BitsInU
nignedInt - OneEighth);
         unsigned int hash              = 0;
         unsigned int test              = 0;

         while (*str)
         {
                 hash = (hash << OneEighth) + (*str++);
                 if ((test = hash & HighBits) != 0)
                 {
                         hash = ((hash ^ (test >> ThreeQuarters)) & (~HighBits)
);
                 }
         }

         return (hash & 0x7FFFFFFF);
}

// ELF Hash Function
unsigned int ELFHash(char *str)
{
         unsigned int hash = 0;
         unsigned int x     = 0;

         while (*str)
         {
                 hash = (hash << 4) + (*str++);
                 if ((x = hash & 0xF0000000L) != 0)
                 {
                         hash ^= (x >> 24);
                         hash &= ~x;
                 }
         }

         return (hash & 0x7FFFFFFF);
}

// BKDR Hash Function
unsigned int BKDRHash(char *str)
{
         unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
         unsigned int hash = 0;

         while (*str)
         {
                 hash = hash * seed + (*str++);
         }

         return (hash & 0x7FFFFFFF);
}

// SDBM Hash Function
unsigned int SDBMHash(char *str)
{
         unsigned int hash = 0;

         while (*str)
         {
                 hash = (*str++) + (hash << 6) + (hash << 16) - hash;
         }

         return (hash & 0x7FFFFFFF);
}

// DJB Hash Function
unsigned int DJBHash(char *str)
{
         unsigned int hash = 5381;

         while (*str)
         {
                 hash += (hash << 5) + (*str++);
         }

         return (hash & 0x7FFFFFFF);
}
// AP Hash Function
unsigned int APHash(char *str)
{
         unsigned int hash = 0;
         int i;
         for (i=0; *str; i++)
         {
                 if ((i & 1) == 0)
                 {
                         hash ^= ((hash << 7) ^ (*str++) ^ (hash >> 3));
                 }
                 else
                 {
                         hash ^= (~((hash << 11) ^ (*str++) ^ (hash >> 5)));
                 }
         }
         return (hash & 0x7FFFFFFF);}

#5


想控制精确就添加一个求余的hash。

#1


把字符串的每个字符乘法一遍。。看你要求什么精度

#2


数值范围最好和字符串的数量相同,

这个很难实现

#3


常用的hash有sdbm, djb2, crc32。

对于不固定的字符串集合来说,不太可能hash函数值和字符串数量相同

对于固定的字符串集合,可以把重复的去掉,给每个剩下的字符串指定一个id, 这个id可以作为一个hash

#4



// RS Hash Function
unsigned int RSHash(char *str)
{
         unsigned int b = 378551;
         unsigned int a = 63689;
         unsigned int hash = 0;

         while (*str)
         {
                 hash = hash * a + (*str++);
                 a *= b;
         }

         return (hash & 0x7FFFFFFF);
}

// JS Hash Function
unsigned int JSHash(char *str)
{
         unsigned int hash = 1315423911;

         while (*str)
         {
                 hash ^= ((hash << 5) + (*str++) + (hash >> 2));
         }
        
         return (hash & 0x7FFFFFFF);
}

// P. J. Weinberger Hash Function
unsigned int PJWHash(char *str)
{
         unsigned int BitsInUnignedInt = (unsigned int)(sizeof(unsigned int) * 
8);
         unsigned int ThreeQuarters     = (unsigned int)((BitsInUnignedInt   * 3)
/ 4);
         unsigned int OneEighth         = (unsigned int)(BitsInUnignedInt / 8);

         unsigned int HighBits          = (unsigned int)(0xFFFFFFFF) << (BitsInU
nignedInt - OneEighth);
         unsigned int hash              = 0;
         unsigned int test              = 0;

         while (*str)
         {
                 hash = (hash << OneEighth) + (*str++);
                 if ((test = hash & HighBits) != 0)
                 {
                         hash = ((hash ^ (test >> ThreeQuarters)) & (~HighBits)
);
                 }
         }

         return (hash & 0x7FFFFFFF);
}

// ELF Hash Function
unsigned int ELFHash(char *str)
{
         unsigned int hash = 0;
         unsigned int x     = 0;

         while (*str)
         {
                 hash = (hash << 4) + (*str++);
                 if ((x = hash & 0xF0000000L) != 0)
                 {
                         hash ^= (x >> 24);
                         hash &= ~x;
                 }
         }

         return (hash & 0x7FFFFFFF);
}

// BKDR Hash Function
unsigned int BKDRHash(char *str)
{
         unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
         unsigned int hash = 0;

         while (*str)
         {
                 hash = hash * seed + (*str++);
         }

         return (hash & 0x7FFFFFFF);
}

// SDBM Hash Function
unsigned int SDBMHash(char *str)
{
         unsigned int hash = 0;

         while (*str)
         {
                 hash = (*str++) + (hash << 6) + (hash << 16) - hash;
         }

         return (hash & 0x7FFFFFFF);
}

// DJB Hash Function
unsigned int DJBHash(char *str)
{
         unsigned int hash = 5381;

         while (*str)
         {
                 hash += (hash << 5) + (*str++);
         }

         return (hash & 0x7FFFFFFF);
}
// AP Hash Function
unsigned int APHash(char *str)
{
         unsigned int hash = 0;
         int i;
         for (i=0; *str; i++)
         {
                 if ((i & 1) == 0)
                 {
                         hash ^= ((hash << 7) ^ (*str++) ^ (hash >> 3));
                 }
                 else
                 {
                         hash ^= (~((hash << 11) ^ (*str++) ^ (hash >> 5)));
                 }
         }
         return (hash & 0x7FFFFFFF);}

#5


想控制精确就添加一个求余的hash。