Algorithm 创建非贪婪LZW算法
基本上,我正在为计算机科学做一篇IB扩展文章,并考虑使用LZW算法的非贪婪实现。我找到了以下链接: 并且在假设论文1中描述的算法和论文2中的LZW-FP基本相同的情况下运行。不管怎样,追踪论文1中的伪代码都是一次痛苦的经历,毫无收获,用我老师的话来说“难以置信地难以理解”。如果有人能找出如何追踪它,或者碰巧以前研究过该算法并知道它是如何工作的,那将是一个很大的帮助。注意:我指的是你所说的“纸1”as和“纸2”as。我在Horspool 1995中只看了LZW算法,所以如果你指的是LZSS算法,这对你没有多大帮助 我的理解是,Horspool的算法是Matias等人1998年称之为“LZW-FPA”的算法,与他们称之为“LZW-FP”的算法不同;不同之处在于算法决定向字典中添加哪些子字符串的方式“将与LZW添加的子字符串完全相同的子字符串添加到字典中,LZW-FP无法为任何字符串生成更长的压缩序列。LZW-FPA(和Horspool算法)在每个输出周期添加贪婪匹配的后续字符串。这不是相同的子串(因为贪婪匹配不会在LZW中的相同点开始),因此理论上它可能会产生比LZW更长的压缩序列 Horspool的算法实际上非常简单,但它的缺点是在提供的伪代码中有几个愚蠢的错误。实现该算法是检测和修复这些错误的好方法;我将伪代码的注释版本放在下面 LZW类算法将输入分解为一系列块。压缩器维护可用块的字典(带有关联的码字)。最初,字典包含所有单个字符串。然后,它逐步完成输入,在每个点查找字典中该点的最长前缀。找到该块后,它输出其码字,并将该块添加到字典中,并附加下一个输入字符。(因为找到的块是字典中最长的前缀,所以块加上下一个字符不能在字典中。)然后它在块上前进,并在下一个输入点(刚好在它刚刚添加到字典中的块的最后一个字符之前)继续 Horspool的修改还会在每个点查找最长的前缀,并将该前缀扩展一个字符添加到字典中。但它不会立即输出该块。相反,它考虑贪婪匹配的前缀,并为每个前缀计算出下一个贪婪匹配是什么。这使其具有两个块的候选范围;它选择了具有最佳进展的范围。为了避免在搜索过程中占用太多时间,该算法通过将要测试的前缀数量进行参数化,前提是更短的前缀不可能产生更长的范围。(Horspool为这种启发提供了一些证据,尽管您可能希望通过自己的实验来验证这一点。) 在Horspool的伪代码中,α是我所称的“候选匹配”——也就是说,在上一步中找到的贪婪匹配——而βj是输入点在α的第j个前缀之后的贪婪后续匹配。(从末尾开始计算,因此β0正是α的贪婪后继匹配,结果是将K设置为0将产生LZW算法。我认为Horspool在某处提到了这一事实。)L就是α的长度。该算法最终将使用α的某些前缀,可能(通常)全部前缀 下面是图2中Horspool的伪代码及其注释:Algorithm 创建非贪婪LZW算法,algorithm,compression,computer-science,data-compression,Algorithm,Compression,Computer Science,Data Compression,基本上,我正在为计算机科学做一篇IB扩展文章,并考虑使用LZW算法的非贪婪实现。我找到了以下链接: 并且在假设论文1中描述的算法和论文2中的LZW-FP基本相同的情况下运行。不管怎样,追踪论文1中的伪代码都是一次痛苦的经历,毫无收获,用我老师的话来说“难以置信地难以理解”。如果有人能找出如何追踪它,或者碰巧以前研究过该算法并知道它是如何工作的,那将是一个很大的帮助。注意:我指的是你所说的“纸1”as和“纸2”as。我在Horspool 1995中只看了LZW算法,所以如果你指的是LZSS算法
initialize dictionary D with all strings of length 1;
set α = the string in D that matches the first
symbol of the input;
set L = length(α);
while more than L symbols of input remain do
begin
// The new string α++head(β0) must be added to D here, rather
// than where Horspool adds it. Otherwise, it is not available for the
// search for a successor match. Of course, head(β0) is not meaningful here
// because β0 doesn't exist yet, but it's just the symbol following α in
// the input.
for j := 0 to max(L-1,K) do
// The above should be min(L - 1, K), not max.
// (Otherwise, K would be almost irrelevant.)
find βj, the longest string in D that matches
the input starting L-j symbols ahead;
add the new string α++head(β0) to D;
// See above; the new string must be added before the search
set j = value of j in range 0 to max(L-1,K)
such that L - j + length(βj) is a maximum;
// Again, min rather than max
output the index in D of the string prefix(α,j);
// Here Horspool forgets that j is the number of characters removed
// from the end of α, not the number of characters in the desired prefix.
// So j should be replaced with L - j
advance j symbols through the input;
// Again, the advance should be L - j, not j
set α = βj;
set L = length(α);
end;
output the index in D of string α;