【问题标题】:Perfect Hash Function for URLs完美的 URL 哈希函数
【发布时间】:2010-07-09 14:29:54
【问题描述】:

有谁知道一个完美的散列函数适用于 64 位整数的 URL,它对大多数 URL 都表现良好?

【问题讨论】:

  • 如果它是一个完美的哈希,根据定义它表现良好。
  • 为什么没有任何基本的字符串散列函数? URL 只是字符串,在我看来很像其他字符串。如果桶的数量与负载因子相比是不错的,那么任何好的字符串散列函数都应该表现得非常好。
  • @Ira Baxter 抱歉,与可接受的 URL 模式相比,我的意思是在哈希大小方面表现良好。据我了解,“完美散列函数”对某些输入执行没有冲突的映射。
  • ... 对于某些输入。是的,但是 URL 有大量的组合;是否有您想要完美散列的小型、有限大小的子集?如果没有,那么您将无法获得完美的哈希函数。真正的问题是,这重要吗?您没有回答为什么基本字符串哈希对您不起作用的问题。
  • @Ira Baxter 你可能想看看en.wikipedia.org/wiki/Perfect_hash_function

标签: php url hash


【解决方案1】:

如果您不知道您将提前查询的一组键,就不可能创建一个完美的哈希函数。如果您知道这一点,那么您可以使用 gperf 或 cmph 之类的东西为您生成完美的哈希函数。

http://cmph.sourceforge.net/

我假设完美的散列函数并不是你真正想要的,所以你可以使用任何合理的散列函数,比如 murmur 散列或 bob jenkins 散列,以及散列表实现,比如 __gnu_cxx::hash_map或者来自谷歌的dense_hash_map和sparse_hash_map。

http://code.google.com/p/google-sparsehash/ http://sites.google.com/site/murmurhash/ http://burtleburtle.net/bob/hash/doobs.html

【讨论】:

    【解决方案2】:

    发现这个标记为"Base52 url shortener perfect hash function in C" 来自http://lambdajones.com/b52

      const char *b52idx[52] = {
      "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
      "B", "C", "D", "F", "G", "H", "J", "K", "L", "M",
      "N", "P", "Q", "R", "S", "T", "V", "W", "X", "Y",
      "Z", "b", "c", "d", "f", "g", "h", "j", "k", "l",
      "m", "n", "p", "q", "r", "s", "t", "v", "w", "x",
      "y", "z"
    };
    
    #define X 0xff
    const int b52map[128] = {
       X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
       X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
       X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
    // 0  1  2  3  4  5  6  7  8  9
       0, 1, 2, 3, 4, 5, 6, 7, 8, 9, X, X, X, X, X, X,
    //       B  C  D     F  G  H     J  K  L  M  N
       X, X,10,11,12, X,13,14,15, X,16,17,18,19,20, X,
    // P  Q  R  S  T     V  W  X  Y  Z
      21,22,23,24,25, X,26,27,28,29,30, X, X, X, X, X,
    //       b  c  d     f  g  h     j  k  l  m  n
       X, X,31,32,33, X,34,35,36, X,37,38,39,40,41, X,
    // p  q  r  s  t     v  w  x  y  z
      42,43,44,45,46, X,47,48,49,50,51, X, X, X, X, X
    };
    
    #ifdef __GNUC__
    #define likely(x) __builtin_expect((x),1)
    #else
    #define likely(x) (x)
    #endif
    
    /*
      valid from 00000 -> zzzzz, good for 380204032 urls
      returns the integral short url id
    */
    unsigned long long b52(const char *c) {
      unsigned long long x = 0;
      unsigned long long y = 0;
      unsigned long long z = 0;
    
      x |= b52map[c[0]] << 24 | b52map[c[1]] << 18 | \
           b52map[c[2]] << 12 | b52map[c[3]] << 6  | b52map[c[4]];
    
      y += (x/64) * 12;
      if (x > 4095) y += 624 * (x/4096);
      if (x > 262143) y += 32448 * (x/262144);
      if (x > 16777215) y += 1687296 * (x/16777215);
    
      if (likely((z = x - y) < 380204033)) return z;
      else return 380204033;
    }
    
    void b52inc(char *id) {
      int x[5] = {
        b52map[id[0]], b52map[id[1]], b52map[id[2]],b52map[id[3]], b52map[id[4]]
      };
      int y = 5;
    
      // search for the first character we can increment (51 == 'z')
      // increment from the b52idx table and update id
      while (y--) if (x[y] < 51) break;
      id[y] = *b52idx[++x[y]];
    
      // if we passed over id's 'z's above, roll them over
      while (y++ < 5) if (x[y] == 51) id[y] = '0';
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 2019-05-22
      • 1970-01-01
      • 2022-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多