信息检索第三次实验--可变字节码的编码和解码算法实现

算法概述:

        可变字节码VB利用整数个字节对间距编码和解码,能够在时间和空间上达到一个非常好的平衡点。

算法设计:

        编码辅助函数、编码函数、解码函数、间距计算函数和计算倒排记录表函数实现VB的编码和解码过程,当用户输入原始倒排记录表后,系统可以计算输出间距记录表、可变字节码,并通过解码函数对可变字节码进行解码得到原始倒排记录表。设计思路如下:

开始\Rightarrow编码\Rightarrow解码\Rightarrow结束

编码过程:

解码过程:

代码实现:

# 编码辅助函数
def VBEncodeNumber(n):
    by, byte = '', []
    while True:
        byte.insert(0, n % 128 + 128)   # 向列表的第 0 位添加元素()
        if n < 128:
            break
        n = n // 128
    for i in range(len(byte)):
        if i < len(byte) - 1:
           by += bin(byte[i]).replace('0b1', '0') + ' '
        else:
           by += bin(byte[i]).replace('0b', '')
    return by


# 编码函数
def VBEncode(numbers):  # 输入一个差值列表
    bytestream = []     # 定义一个空列表
    for n in numbers:   # 遍历距离差值列表元素
        byte = VBEncodeNumber(n)  # 将该值进行进制转换(10--2)
        bytestream.append(byte)   # 将该数据的二进制形式添加至列表中
    return bytestream   # 返回差值(二进制形式)列表


# 解码函数
def VBDecode(bytestream):  # 输入编码后的列表
    numbers = []  # 初始化空列表
    n = 0
    for i in range(len(bytestream)):
        byte = bytestream[i].split(' ')  # 将每个元素的各个八位二进制数进行切分
        l = len(byte)       # 记录有多少个八位二进制数
        for j in range(l):  # 遍历每八位个二进制数进行数值转换
            if j < 1 - 1:
                by = int('0b1' + byte[j][1: len(byte[j])], 2)
            else:
                by = int('0b' + byte[j], 2)
            n = 128*n + by if by < 128 else 128*(n - 1) + by
        numbers.append(n)  # 将每个计算好的十进制数加入到列表中
        n = 0
    return numbers  # 返回编码后十进制数的列表


# 计算倒排记录表间距函数
def countdaopaidis(daopai):
    daopaidis = daopai.copy()         # 初始化差值函数
    for i in range(len(daopai)):
        if i == 0:
            daopaidis[i] = daopai[i]  # 第 0 位设为原第 0 位的值
        else:
            daopaidis[i] = daopai[i] - daopai[i - 1]  # 其余位设置为该位与其前一位的差值
    return daopaidis  # 返回间距列表


# 计算倒排记录表函数
def countdaopai(daopaidis):     # 输入一个十进制数的列表
    daopai = daopaidis.copy()   # 初始化一个空列表,存放计算出的原始倒排表
    for i in range(len(daopaidis)):
        daopai[i] = sum(daopaidis[0: i + 1])  # 计算每个原始数据(分别是从第0为开始到该位元素之间各个元素的和)
    return daopai  # 返回解码之后的数据列表


# 主函数
if __name__ == '__main__':
    daopai = [777, 17743, 294068, 31251336]
    print('原始倒排记录表为:\n', daopai, '\n')
    daopaidis = countdaopaidis(daopai)
    print('间距记录表为:\n', daopaidis, '\n')
    bytestream = VBEncode(daopaidis)  # 编码
    print('可变字节码为:\n', bytestream, '\n')
    daopaidis = VBDecode(bytestream)  # 解码
    daopai = countdaopai(daopaidis)
    print('解码得到的倒排记录表为:\n', daopai, '\n')

猜你喜欢

转载自blog.csdn.net/rui_qi_jian_xi/article/details/130155888