我需要计算二进制字符串的LZ复杂度。 LZ复杂度是从开始到结束查看流时遇到的差异子串的数量。举个例子:
s = 1001111011000010
在不同的子串中标记序列复杂度c(s)= 6: s = 1/0/101 / 1110/1100/20010 /
有人可以指导我找到一个简单的解决方案吗?我确信这个众所周知的问题应该有一些非常简单的实现,但我很难找到它们。可以通过构造后缀树或类似的东西来完成。如果是,究竟如何?我该怎么办?
任何人都知道要完成任务的任何c / c ++源代码吗?
提前感谢。
澄清答案中建议的树的构造。这棵树看起来像这样吗?
o
/ \
o o
/ \ / \
o o o o
/ /
o o
答案 0 :(得分:1)
下面是如何使用树计算LZ复杂度的快速示例。为方便起见 - 我的;不是你的 - 这段代码实现了一个固定大小的预分配树,并且是为什么void *指针难以使用且难以维护的一个主要例子。按原样输入此代码,您的讲师可能会对您开枪:)
#include <stdlib.h>
#include <stdio.h>
int LZComplexity(char *p_binarySequence, int p_maxTreeNodes)
{
void **patternTree;
void **currentNode;
void **nextFreeNode;
int nodeCount;
int sequenceIndex;
int currentDigit;
nodeCount = 0;
patternTree = malloc(sizeof(void*) * (p_maxTreeNodes << 1));
currentNode = patternTree;
nextFreeNode = patternTree + (sizeof(void*) << 1);
currentNode[0] = NULL;
currentNode[1] = NULL;
sequenceIndex = 0;
while (p_binarySequence[sequenceIndex])
{
currentDigit = p_binarySequence[sequenceIndex] - 48;
if (NULL == currentNode[currentDigit])
{
currentNode[currentDigit] = nextFreeNode;
nextFreeNode[0] = NULL;
nextFreeNode[1] = NULL;
nextFreeNode += (sizeof(void*) << 1);
currentNode = patternTree;
nodeCount++;
}
else
{
currentNode = currentNode[currentDigit];
}
sequenceIndex++;
}
free(patternTree);
return nodeCount;
}
int main(int argc, char *argv[])
{
printf("%u\n", LZComplexity("10100101001011101011", 1000));
return 0;
}
答案 1 :(得分:1)
1 0 01 11 10 110 00 010
序列的复杂性是8,因为分区是8而不是6 - 1/0/01/11/10/110/00/010
答案 2 :(得分:1)
@Arash和@Sanchit Gupta:你可能会对LZ76复杂性和LZ78复杂性感到困惑。 Arash所指的是LZ76的复杂性,另一个是LZ78的复杂性。你可以参考文章“通过Lempel-Ziv复杂性估算穗列车的熵率”一节。
答案 3 :(得分:1)
答案 4 :(得分:0)
创建一个二叉树,其中左边是0,右边是1.对于每个位,尝试在树中查找序列。如果它在那里,连接下一位,冲洗,重复。如果不存在,请将其添加到树中继续。 LZ Complexity是树中路径的总数(不仅仅是#叶节点)。
顺便问一下,这是homework
吗?
答案 5 :(得分:0)
这应该是Python中的技巧(来自:Kaspar,F。Schuster,H。易于计算的时空模式复杂度。物理评论A,第36卷,第2页,p 842。)
#!/usr/bin/python
def lz_complexity(s):
i, k, l = 0, 1, 1
k_max = 1
n = len(s) - 1
c = 1
while True:
if s[i + k - 1] == s[l + k - 1]:
k = k + 1
if l + k >= n - 1:
c = c + 1
break
else:
if k > k_max:
k_max = k
i = i + 1
if i == l:
c = c + 1
l = l + k_max
if l + 1 > n:
break
else:
i = 0
k = 1
k_max = 1
else:
k = 1
return c
def main():
lz = lz_complexity('1001111011000010')
assert lz == 6
print lz
if __name__ == '__main__':
main()
答案 6 :(得分:0)
这可能与您相关。它是并行实现 计算LZ复杂度的算法LZMP 在CUDA中并在nVidia GPU上运行。