个人网站:eteluna.top
这门课的上机题目还都挺有意思,尤其是第三个LSH索引耗费了不少精力,故记录下来。
编程语言为 Python 3
1. LZW 编码算法
如果字典数超过 10 可能会出 bug,因为编码是 1 位的(可通过增加编码位数解决)
算法流程:
- 对输入字符串初始化生成单字符的字典,设P为空字符串;
- 遍历字符串每一位C,判断P+C是否在字典中,若是则将P+C赋予P,否则在字典中添加P+C,在结果添加P对应的值,并将C赋予P;
- 最后一位字符在结果添加P的值;
- 输出编码结果与字典;
- 解码程序拿到编码结果与初始化的单字符字典;
- 将字典键值翻转,对编码的每一位求得对应字符前缀,保存到字典;
- 除第一次,将前缀添加到上一条的末尾,并更新前缀,记录;
- 输出记录下的字符。
def init(s):
# s: 输入字符串
# 返回: 包含所有单字符的字典
table = {
}
tmp = []
for i in s:
if i not in tmp:
tmp.append(i)
j = 1
for i in range(len(tmp)):
t = str(j)
table[tmp[i]] = t
j = j + 1
return table
def encoding(s):
# s: 输入字符串
# r: 编码结果 table: 编码表,初始化是单字符字典
r = []
table = init(s)
P = ''
for i in range(len(s)):
C = s[i]
t = P+C
# 判断 P+C 是否在词典中
if t in table.keys():
P = t
if t not in table.keys():
table[t] = str(len(table)+1)
r.append(table[P])
P = C
# 最后一位用单字符编码表示
if i == len(s)-1:
r.append(table[P])
print("After compress: " + ''.join(r))
print("coding table is: ")
print(table)
# 将单字符字典与编码结果传入 decoding 解码
default = init(s)
decoding(default,r)
def decoding(table,r):
# table:包含单独字符的字典, r: LZW编码
inverse_table = dict(zip(table.values(),table.keys()))
num = len(table.keys())
tablelen = num
tem = []
for i in range(len(r)):
# P 前缀
P = inverse_table[str(r[i])]
inverse_table[str(num+1)] = P
# 除第一个编码外,前缀第一个字符添加到上一条的末尾
if num > tablelen:
inverse_table[str(num)] = inverse_table[str(num)]+P[0]
# 重新获取前缀,添加至 tem
P = inverse_table[str(r[i])]
tem.append(P)
num = num+1
print("decoding:"+''.join(tem))
测试:
input a string: abababcabcab
After compress: 1244374
coding table is:
{'a': '1', 'b': '2', 'c': '3', 'ab': '4', 'ba': '5', 'aba': '6', 'abc': '7', 'ca': '8', 'abca': '9'}
decoding:abababcabcab
2. k-l 变换与矢量量化
在 ColorHistogram.asc
数据集上实现 k-l 变换
算法流程:
- 将