在java中实现patricia trie

时间:2012-10-28 18:07:41

标签: java c++ trie radix

我正在尝试在java中重写c ++ patricia trie。 c ++代码来自here

full source code

我有点卡住了。

所以这是我的理解:

#define ZEROTAB_SIZE 256
head->key = (char*)calloc(ZEROTAB_SIZE, 1);

我们为密钥创建一个256位的数组,因此我们可以得到一个最大长度为32个字符的字符串,每个字符用8位表示。我可以用java中的char数组实现吗?

template <class T>
int PatriciaTrie<T>::bit_get(PatriciaTrieKey bit_stream, int n) {
  if (n < 0) return 2; // "pseudo-bit" with a value of 2.
  int k = (n & 0x7);
  return ( (*(bit_stream + (n >> 3))) >> k) & 0x1;
}

k得到n的最后7位,我们移动到字符串的n / 8字符(不完全是n / 8,因为向右移动会删除低于8到0的任何值)然后我们移动bit_stream的值[n>&gt; 3]用k然后我们得到最后一位。如果我在java中使用数组,我可以将其重写为

return (bit_stream[n>>3] >> k) & 0x1;

template <class T>
int PatriciaTrie<T>::bit_first_different(PatriciaTrieKey k1, PatriciaTrieKey k2) {
    if (!k1 || !k2)
        return 0; // First bit is different!
    int n = 0;
    int d = 0;
    while ( (k1[n] == k2[n]) &&
            (k1[n] != 0) &&
            (k2[n] != 0) )
        n++;
    while (bit_get(&k1[n], d) == bit_get(&k2[n], d))
        d++;
    return ((n << 3) + d);
}

现在这是令人困惑的地方,第一部分直到第二部分while循环看起来足够清楚,循环并检查多少位相等且非零,但我不确定第二循环在做什么,我们取两个键的地址并检查它们是否相等的第一位,如果它们是我们再次检查,直到找到不相等的位?

主要是我不确定如何在这里使用密钥的地址,但我也可能对bit_get类中的位移位感到困惑。

我想在c ++和java中为我的java类进行比较,我希望尽可能保持类似的实现。

2 个答案:

答案 0 :(得分:2)

我不熟悉这种数据结构,但是您对此代码的理解存在一些问题。

首先,calloc分配256个字节,而不是位。 new byte[256]在java中具有可比性。

其次,n & 0x7得到三位n,而不是七位。更清楚的方法是n/8n%8而不是n>>3n & 7,但如果你的编译器是愚蠢的,那么按位运算可能会稍快一些。

(bit_stream[n>>3]>>k) & 1是一样的。

现在,bit_first_different中的第一个循环遍历字节,而不是位。检查0是为了防止关闭键的结束。一旦该循环终止,n指的是第一个不同的字节。然后第二个循环寻找哪个位不同。

请注意,如果两个键没有区别,那么第二个循环可能会在键的末尾运行,可能会导致分段错误。

现在,&amp;取k1[n]的地址,因为bit_get函数期望指向字符的指针...这会传递位流的n元素。在循环之后,dk[n]的第一个不同位的偏移量。

最后,代码将n(哪个字节?)与d(该字节中的哪个位?)组合在一起。我再次主张8*n+d以澄清,但这只是一种品味问题。

答案 1 :(得分:0)

  

我可以在java中用char数组实现吗?

我的java有点生疏,但我相信char已在java中签名,这意味着>>将无法达到您的预期。那是因为移位带符号的数字不会改变符号位,所以你真正想要的是>>>运算符,或者只使用无符号的byte类型。我有一种感觉,这是各种错误所以请仔细检查。

  

return(bit_stream [n>&gt;&gt; 3]&gt;&gt; k)&amp;为0x1;

在C或C ++中,*(array + k)只是另一种写array[k]的方式,因此您的翻译看起来是正确的。至于解释,bit_stream[n>>3]基本上取出了所需位所在的字节。 >> k在最低有效位位置移动所需位。最后,我们通过使用& 0x1屏蔽它们来删除我们不感兴趣的所有位。这给我们留下0或1的值,具体取决于该位是否已设置。

最终函数的作用是比较2位字符串并返回2个字符串首先不同的位位置。第一个循环本质上是第二个循环的优化版本,而不是逐位比较,而是检查整个字节。

换句话说,它首先遍历每个字节并找到不同的前两个字节。然后它获取这2个不同的字节并循环它们,直到它找到不同的前2位。请注意,在这种情况下,bit_get函数永远不会收到大于7的n,因为我们知道字节中的某处存在差异。然后根据两个循环的结果构造最终的位位置,如:(number_of_equal_bytes * 8) + number_of_equal_bits)

相关问题