implementing a patricia trie in java

implementing a patricia trie in java

本文关键字:in java trie patricia implementing      更新时间:2023-10-16

我正在尝试在Java中重写C Patricia Trie。C 代码来自此处

完整的源代码

我有点卡住。

所以这是我的理解:

#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,我们移动到字符串的N/8个字符(不完全n/8,因为向右移动将删除低于8到零的内容),然后我们移动BIT_STREAM的值[n>> 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);
}

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

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

我想对我的Java类中的trie进行比较,我想保持实现尽可能相似。

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

首先,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为了清楚起见,但这是一个品味问题。

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

我的Java有点生锈,但我相信char在Java签名,这意味着>>不会做您期望的。那是因为移动签名的数字不会移动符号位,因此您真正想要的是>>>操作员,或者仅使用未签名的byte类型。我觉得这是各种各样的错误,所以请仔细检查。

返回(bit_stream [n>> 3]>> k)&amp;0x1;

在C或C 中,*(array + k)只是编写array[k]的另一种方法,因此您的翻译看起来正确。至于解释,bit_stream[n>>3]基本上获取所需位的字节。>> k将所需的位移动至最不重要的位位置。最后,我们通过用& 0x1掩盖了它们不感兴趣的所有位。这使我们的值为0或1的值,具体取决于钻头是否设置。

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

换句话说,它首先在每个字节上循环,然后找到不同的两个字节。然后,将这两个不同的字节和循环循环到它们上,直到发现前2位不同。请注意,在这种情况下,bit_get函数永远不会接收N更大的7,因为我们知道字节中的某个地方有区别。然后从两个循环的结果构建最终位置位置,例如: (number_of_equal_bytes * 8) + number_of_equal_bits)