我为实现以下示例字符串的lempel ziv压缩算法编写了以下代码:
AAAABBCDEABCDABCAAABCDEEEEEECBBBBBBDDAAE
代码:
keys=[]
text = open('test').read() # contain of the string: AAAABBCDEABCDABCAAABCDEEEEEECBBBBBBDDAAE
index=0
t=time.time()
def sub_strin_check(text,index_num):
n = 1
while True:
substring = text[index_num:index_num+n]
if substring not in keys :
print(substring)
keys.append(substring)
# print(keys[-1])
return (index_num+n)
else:
n = n+1
continue
while True:
try:
if text[index] not in keys:
# print (index)
keys.append(text[index])
print(keys.append(text[index]),text[index])
except:
break
else:
try:
index = sub_strin_check(text,index)
print(index)
print(index)
index = index + 1
except:
break
res = str(keys)
print(res)
with open("result","w") as f:
f.write(res)
但结果是:
['A', 'A', 'AA', 'AB', 'C', 'C', 'CD', 'ABC', 'ABCA', 'ABCD', 'E', 'E', 'EE', 'EEC', 'B', 'B', 'BB', 'BBD', 'AAE']
我的想法是使用字符串中的索引号(文本),并检查切片中的子串是否在键字典或螺母中退出,如果不存在,则添加它。如果存在,则通过添加下一个字符来检查子串。
请帮忙看看我的错误在哪里?
PS:我知道因特网上有一些lempel-ziv-python代码,但是我必须使用这些代码。
PPS:
lempel-ziv算法就是这样工作的检查在给定字符串中的第一个字符,如果它不存在于字符串中的下一个字符的检查中,并且检查这个新的子串,如果它不退出,则添加子串,如果在键中退出,则添加下一个字符,并且这个过程继续…例如,对于我的字符串,输出应该是:
[A,AA,AB,B,C,D,ABC,AAA,BC,DE,E,EE,EEE,CB,BB,BBB,DD,AAE]
最佳答案
我会用字典而不是列表来查找。如果需要,从字典到列表的转换是直接的
input_str = 'AAAABBCDEABCDABCAAABCDEEEEEECBBBBBBDDAAE'
keys_dict = {}
ind = 0
inc = 1
while True:
if not (len(input_str) >= ind+inc):
break
sub_str = input_str[ind:ind + inc]
print sub_str,ind,inc
if sub_str in keys_dict:
inc += 1
else:
keys_dict[sub_str] = 0
ind += inc
inc = 1
# print 'Adding %s' %sub_str
print list(keys_dict)
输出:
['A', 'AA', 'C', 'B', 'E', 'D', 'BB', 'BC', 'BCD', 'BBB', 'ABC', 'DA', 'EE', 'AB', 'EC', 'BD', 'EEE', 'AAA', 'DAA']
算法参考:
https://www.youtube.com/watch?v=EgreLYa-81Y