29位有序序列的无损压缩(每个0到5个李克特量表)

时间:2016-01-23 23:27:30

标签: algorithm compression

我有一个包含29个问题的调查,每个问题都有一个5分的李克特量表(0 =没有时间; 4 =大部分时间)。我想将一组响应压缩为少量的字母或字母数字字符,并在末尾添加一个校验位。

因此,响应集var result = RunCommand<SomeOtherType>(q => q.Where(x => ....).Select(x => ....)); 将转变为类似00101244231023110242231421211的内容。此输出将是非技术用户在网站上输入的打印输出的一部分,作为输入整个字符串的快捷方式。我想避免模糊的字符,例如A2CR7HW4,让我使用21或22个字符(仅限大写)。或者,我可以只使用大写字母,并使用全部26个字符。

我正在考虑将每对数字转换成一个字母(5 ^ 2 = 25,因此整个字母表就足够了)。这会将序列减少到15个字符,这仍然很长,无错误地输入。

关于如何最小化输出长度的任何其他建议?

编辑:BTW,就上下文而言,该调查询问了29个关于精神健康症状的问题,为4种精神疾病产生了预测风险。需要一个代表所有回复的代码。

3 个答案:

答案 0 :(得分:2)

如果五个答案都具有相同的可能性,那么您可以做的最好的是ceiling(29 * log(5) / log(n))个符号,其中n是字母表中符号的数量。 (对数的基数并不重要,只要它们都是相同的。)

因此对于你的22个符号,你能做的最好的是16个。对于26个符号,最好的是15,如你所描述的25个。如果你使用49个字符(例如大写和小写字符的某个子集和数字),你可以降到12.你可以使用可打印的ASCII字符最好的是11,使用94个字符中的70个。

使其变小的唯一方法是,如果响应同样可能并且严重偏斜。虽然如果是这样的话,那么调查可能有些不对劲。

答案 1 :(得分:1)

首先,选择一组允许的字符,即

characters = "ABC..."

然后,在输入数字前加1,并将其解释为一个五进制数:

100101244231023110242231421211

现在,将此序号转换为基数 - &#34; strlen(字符)&#34;,即如果要使用26个字符,则为base26:

02 23 18 12 10 24 04 19 00 15 14 20 00 03 17

然后,在&#34;字符&#34;中使用这些数字作为索引,您就拥有了编码:

CVSMKWETAPOUADR

对于解码,只需颠倒步骤即可。

答案 2 :(得分:0)

你是用特定语言做的吗?

如果您想要真正节俭,可能需要考虑在位级编码数据。

由于每个问题只有5个可能的答案,因此只需3位即可:

000
001
010
011
100

您的最终结果将是一串位,每个答案为3位,因此总共87位或10位和一位字节。

编辑 - 稍微误读了这个问题,有5个可能的答案不是4,我的错误。

现在唯一的问题是,对于你的5个答案中的4个,你会浪费一点......你不会因为遇到这么多麻烦而受益匪浅,我不会说但是值得考虑。

编辑:

我一直在玩它,并且很难找到一种允许你同时使用2位和3位值的机制。

由于您的输出是97位二进制值,因此在转换回原始值时,您需要能够区分2到3位值。

如果您正在使用大量值,则可以使用一些方法,例如为每个值设置一个保留位,可用于对值进行排序并赋予其一些含义。但是如果处理这么少的东西,就很难剃掉任何东西。

您的97位输出可以填充为128位,如果您想简化它,将为您提供4个32位值。这个128位值就像一个代表一组特定答案的唯一指纹。有很多方法可以代表128位。

但最终在位级别的borking与实际压缩和数据编码一样好...如果你能在不到3位中表达5个唯一值,我会给你留下深刻的印象