我正在研究算术编码和解码算法的自适应实现,并且已经实现了python,但是对于某些字符串,我得到了正确的答案,但对于其他字符串,我得到了正确的答案。

程序首次启动时,会提供一个参数来决定符号概率的更改频率。 例如,如果参数为10,则在发送/接收10个符号之后,概率表会根据到目前为止发送/接收的所有符号进行更改。 因此,域分配也被更改。 最初,我具有1/26概率的均匀分布[az]。

它不适用于“ heloworldheloworld”和许多其他情况。

另外,我已经了解了下溢问题,但是如何解决该问题。

import sys
import random
import string


def encode(encode_str, N):
    count = dict.fromkeys(string.ascii_lowercase, 1)                                        # probability table
    cdf_range = dict.fromkeys(string.ascii_lowercase, 0)
    pdf = dict.fromkeys(string.ascii_lowercase, 0)

    low = 0
    high = float(1)/float(26)

    for key, value in sorted(cdf_range.iteritems()):
        cdf_range[key] = [low, high]
        low = high
        high += float(1)/float(26)

    for key, value in sorted(pdf.iteritems()):
        pdf[key] = float(1)/float(26)

    # for key, value in sorted(cdf_range.iteritems()):
    #   print key, value

    # for key, value in sorted(pdf.iteritems()):
    #   print key, value

    i = 26

    lower_bound = 0                                                                     # upper bound
    upper_bound = 1                                                                     # lower bound

    u = 0

    # go thru every symbol in the string
    for sym in encode_str:
        i += 1
        u += 1
        count[sym] += 1

        curr_range = upper_bound - lower_bound                                          # current range
        upper_bound = lower_bound + (curr_range * cdf_range[sym][1])                    # upper_bound
        lower_bound = lower_bound + (curr_range * cdf_range[sym][0])                    # lower bound

        # update cdf_range after N symbols have been read
        if (u == N):
            u = 0

            for key, value in sorted(pdf.iteritems()):
                pdf[key] = float(count[key])/float(i)

            low = 0
            for key, value in sorted(cdf_range.iteritems()):
                high = pdf[key] + low
                cdf_range[key] = [low, high]
                low = high

    return lower_bound

def decode(encoded, strlen, every):
    decoded_str = ""

    count = dict.fromkeys(string.ascii_lowercase, 1)                                        # probability table
    cdf_range = dict.fromkeys(string.ascii_lowercase, 0)
    pdf = dict.fromkeys(string.ascii_lowercase, 0)

    low = 0
    high = float(1)/float(26)

    for key, value in sorted(cdf_range.iteritems()):
        cdf_range[key] = [low, high]
        low = high
        high += float(1)/float(26)

    for key, value in sorted(pdf.iteritems()):
        pdf[key] = float(1)/float(26)


    lower_bound = 0                                                                     # upper bound
    upper_bound = 1                                                                     # lower bound

    k = 0

    while (strlen != len(decoded_str)):
        for key, value in sorted(pdf.iteritems()):

            curr_range = upper_bound - lower_bound                                      # current range
            upper_cand = lower_bound + (curr_range * cdf_range[key][1])                 # upper_bound
            lower_cand = lower_bound + (curr_range * cdf_range[key][0])                 # lower bound

            if (lower_cand <= encoded < upper_cand):
                k += 1
                decoded_str += key

                if (strlen == len(decoded_str)):
                    break

                upper_bound = upper_cand
                lower_bound = lower_cand

                count[key] += 1

                if (k == every):
                    k = 0
                    for key, value in sorted(pdf.iteritems()):
                        pdf[key] = float(count[key])/float(26+len(decoded_str))

                    low = 0
                    for key, value in sorted(cdf_range.iteritems()):
                        high = pdf[key] + low
                        cdf_range[key] = [low, high]
                        low = high

    print decoded_str

def main():
    count = 10
    encode_str = "yyyyuuuuyyyy"
    strlen = len(encode_str)
    every = 3
    encoded = encode(encode_str, every)
    decoded = decode(encoded, strlen, every)

if __name__ == '__main__':
    main()

===============>>#1 票数:1

错误出现在大约12个字符长的字符串上。 这接近python使用的双精度,可能会引起您的问题。

我对BigFloat库(具有任意精度)进行了快速测试,并获得了正确的答案:

import sys
import random
import string
from bigfloat import *

factor = BigFloat(1)/BigFloat(26)

def encode(encode_str, N):
    count = dict.fromkeys(string.ascii_lowercase, 1)                                        # probability table
    cdf_range = dict.fromkeys(string.ascii_lowercase, 0)
    pdf = dict.fromkeys(string.ascii_lowercase, 0)

    with precision(200) + RoundTowardZero:
        low = 0
        high = factor

        for key, value in sorted(cdf_range.iteritems()):
            cdf_range[key] = [low, high]
            low = high
            high += factor

        for key, value in sorted(pdf.iteritems()):
            pdf[key] = factor

        # for key, value in sorted(cdf_range.iteritems()):
        #   print key, value

        # for key, value in sorted(pdf.iteritems()):
        #   print key, value

        i = 26

        lower_bound = 0                         # upper bound
        upper_bound = 1                         # lower bound

        u = 0

        # go thru every symbol in the string
        for sym in encode_str:
            i += 1
            u += 1
            count[sym] += 1

            curr_range = upper_bound - lower_bound                                          # current range
            upper_bound = lower_bound + (curr_range * cdf_range[sym][1])                    # upper_bound
            lower_bound = lower_bound + (curr_range * cdf_range[sym][0])                    # lower bound

            # update cdf_range after N symbols have been read
            if (u == N):
                u = 0

                for key, value in sorted(pdf.iteritems()):
                    pdf[key] = BigFloat(count[key])/BigFloat(i)

                low = 0
                for key, value in sorted(cdf_range.iteritems()):
                    high = pdf[key] + low
                    cdf_range[key] = [low, high]
                    low = high

    return lower_bound

def decode(encoded, strlen, every):
    decoded_str = ""

    count = dict.fromkeys(string.ascii_lowercase, 1)                                        # probability table
    cdf_range = dict.fromkeys(string.ascii_lowercase, 0)
    pdf = dict.fromkeys(string.ascii_lowercase, 0)


    with precision(200) + RoundTowardZero:
        low = 0
        high = factor

        for key, value in sorted(cdf_range.iteritems()):
            cdf_range[key] = [low, high]
            low = high
            high += factor

        for key, value in sorted(pdf.iteritems()):
            pdf[key] = factor


        lower_bound = BigFloat(0)                           # upper bound
        upper_bound = BigFloat(1)                           # lower bound

        k = 0

        while (strlen != len(decoded_str)):
            for key, value in sorted(pdf.iteritems()):

                curr_range = upper_bound - lower_bound                                      # current range
                upper_cand = lower_bound + (curr_range * cdf_range[key][1])                 # upper_bound
                lower_cand = lower_bound + (curr_range * cdf_range[key][0])                 # lower bound

                if (lower_cand <= encoded < upper_cand):
                    k += 1
                    decoded_str += key

                    if (strlen == len(decoded_str)):
                        break

                    upper_bound = upper_cand
                    lower_bound = lower_cand

                    count[key] += 1

                    if (k == every):
                        k = 0
                        for key, value in sorted(pdf.iteritems()):
                            pdf[key] = BigFloat(count[key])/BigFloat(26+len(decoded_str))

                        low = 0
                        for key, value in sorted(cdf_range.iteritems()):
                            high = pdf[key] + low
                            cdf_range[key] = [low, high]
                            low = high

        print decoded_str

def main():
    count = 10
    encode_str = "heloworldheloworld"
    strlen = len(encode_str)
    every = 3
    encoded = encode(encode_str, every)
    decoded = decode(encoded, strlen, every)

if __name__ == '__main__':
    main()

===============>>#2 票数:1

发生这种情况是因为Python float具有53位精度。 您不能编码很长的字符串。

您可能需要使用decimal而不是floats来获得任意精度

import sys
import random
import string

import decimal
from decimal import Decimal

decimal.getcontext().prec=100

def encode(encode_str, N):
    count = dict.fromkeys(string.ascii_lowercase, 1)                                        # probability table
    cdf_range = dict.fromkeys(string.ascii_lowercase, 0)
    pdf = dict.fromkeys(string.ascii_lowercase, 0)

    low = 0
    high = Decimal(1)/Decimal(26)

    for key, value in sorted(cdf_range.iteritems()):
        cdf_range[key] = [low, high]
        low = high
        high += Decimal(1)/Decimal(26)

    for key, value in sorted(pdf.iteritems()):
        pdf[key] = Decimal(1)/Decimal(26)

    # for key, value in sorted(cdf_range.iteritems()):
    #   print key, value

    # for key, value in sorted(pdf.iteritems()):
    #   print key, value

    i = 26

    lower_bound = 0                                                                     # upper bound
    upper_bound = 1                                                                     # lower bound

    u = 0

    # go thru every symbol in the string
    for sym in encode_str:
        i += 1
        u += 1
        count[sym] += 1

        curr_range = upper_bound - lower_bound                                          # current range
        upper_bound = lower_bound + (curr_range * cdf_range[sym][1])                    # upper_bound
        lower_bound = lower_bound + (curr_range * cdf_range[sym][0])                    # lower bound

        # update cdf_range after N symbols have been read
        if (u == N):
            u = 0

            for key, value in sorted(pdf.iteritems()):
                pdf[key] = Decimal(count[key])/Decimal(i)

            low = 0
            for key, value in sorted(cdf_range.iteritems()):
                high = pdf[key] + low
                cdf_range[key] = [low, high]
                low = high

    return lower_bound

def decode(encoded, strlen, every):
    decoded_str = ""

    count = dict.fromkeys(string.ascii_lowercase, 1)                                        # probability table
    cdf_range = dict.fromkeys(string.ascii_lowercase, 0)
    pdf = dict.fromkeys(string.ascii_lowercase, 0)

    low = 0
    high = Decimal(1)/Decimal(26)

    for key, value in sorted(cdf_range.iteritems()):
        cdf_range[key] = [low, high]
        low = high
        high += Decimal(1)/Decimal(26)

    for key, value in sorted(pdf.iteritems()):
        pdf[key] = Decimal(1)/Decimal(26)


    lower_bound = 0                                                                     # upper bound
    upper_bound = 1                                                                     # lower bound

    k = 0

    while (strlen != len(decoded_str)):
        for key, value in sorted(pdf.iteritems()):

            curr_range = upper_bound - lower_bound                                      # current range
            upper_cand = lower_bound + (curr_range * cdf_range[key][1])                 # upper_bound
            lower_cand = lower_bound + (curr_range * cdf_range[key][0])                 # lower bound

            if (lower_cand <= encoded < upper_cand):
                k += 1
                decoded_str += key

                if (strlen == len(decoded_str)):
                    break

                upper_bound = upper_cand
                lower_bound = lower_cand

                count[key] += 1

                if (k == every):
                    k = 0
                    for key, value in sorted(pdf.iteritems()):
                        pdf[key] = Decimal(count[key])/Decimal(26+len(decoded_str))

                    low = 0
                    for key, value in sorted(cdf_range.iteritems()):
                        high = pdf[key] + low
                        cdf_range[key] = [low, high]
                        low = high

    print decoded_str

def main():
    count = 10
    encode_str = "heloworldheloworld"
    strlen = len(encode_str)
    every = 3
    encoded = encode(encode_str, every)
    decoded = decode(encoded, strlen, every)

if __name__ == '__main__':
    main()

  ask by Pete translate from so

未解决问题?本站智能推荐:

2回复

python中的UTF8编码和解码

我有一个从Java传递到python的UTF8字符串。 最终结果是 因此,例如 给我结果 但是,我很好奇的是,因为字节是以UTF-8的形式传递的,为什么会这样 而不是u'\บ\น' 。 如果我要编码(u'\บ\น')我会返回'\\xe0\\xb8\\x
2回复

如何在python中编码和解码路径?

这是问题,我要在Unix系统下以python转储和加载Windows路径: 那么,我哪里出错了?
3回复

自己在Python中实现对base64文件的编码和解码

我自己的base64编码实现存在问题。 我已经获得了下面的代码。 我想它仅适用于带有英文字母的文本文件。 例如,pdf文件是经过编码和解码的,它不同于单个字符。 我认为,这行“ return text_str.encode(“ UTF-8”)“应该不解码为UTF-8。 但是,如果
4回复

Python编码功能无法解码

我写了这个python代码,试图将对象转换为一串一和零,但是解码失败了,因为无法解开数据。 这是代码:
1回复

在JAVASCRIPT + JSON中编码HTML并在PYTHON中解码HTML的正确方法是什么?

我有一个JAVASCRIPT数组allPois,其中包含几个pois对象,其结构如下: 这是调用我的服务器的JAVASCRIPT函数: 这是服务器端处理请求的功能: 编码/解码参数“ html”(实际上包含html代码)以便可以在服务器中正确加载的最佳方法是什么?
1回复

意外的Python算术行为

我正在使用Python开发霍夫曼编码器/解码器,并且在我的代码中遇到了一些意外的行为(至少对我而言)。 编码文件很好,解码文件时会出现问题。 以下是相关代码: 第一个with open(cfile,"rb") as f调用对于所有文件大小(测试的大小分别为1.2MB,679KB和87
1回复

Python十六进制解码器

嘿我需要解码十六进制并写入文本文件,但我只能编码它不解码。 我编写了一个脚本来编码,它可以工作并打印到名为encoded.txt的文本文件中。 到目前为止,我编码(打印“Hello World!”),它返回7072696e74202248656c6c6f20576f726c642122
2回复

Python编码问题

我有要从Windows 1252中解码的数据,基本上我将代码发送到套接字,然后将其发送回去,我必须解码消息并使用IEEE-754从中获取特定值,但是我可以似乎找出所有这些编码的东西。 这是我的代码。 因此,我使用了它,然后必须从中获得价值。.但是它不起作用,我不知道为什么。 我得
4回复

Python文字编码

我在文件Recuérdame中找到了这段文字(注意这是一个法语单词)。 当我使用python脚本读取该文件时,得到的文本为Recu&#xE9;rdame 。 我将其读取为unicode字符串。 我是否需要查找文本的编码并对此进行解码? 还是我的终端在欺骗我?
1回复

解码包含编码字符的字符串

我有一些字符串要作为测试数据粘贴到脚本中。 字符串来自包含编码字符的电子邮件,并SyntaxError 。 到目前为止,我还没有找到解决此问题的方法。 当我print repr(string) ,我得到了这些字符串: 当我运行脚本时会弹出此错误: 当我只打印包含编码字符的行